E-NO
Bash commands 7 Min Read

Bash Basic Commands with Practical Examples: A Guide for Daily Operations

calendar_today Published: 2026-10-09
update Last Updated: 2026-10-09
analytics SEO Efficiency: 100%
Technical guide illustration for Bash Basic Commands with Practical Examples: A Guide for Daily Operations.

Intro

Every operator has experienced the moment when a production issue appears and the only tool available is a terminal. Bash is the common language of Linux and macOS environments, and knowing a focused set of basic commands with practical examples turns panic into a repeatable procedure. This guide is built for developers, DevOps consultants, and technical startup teams who need to diagnose, configure, verify, and recover services without guessing.

The goal is operational safety: observe before changing, limit the blast radius, use placeholders instead of secrets, verify the result, and document how to recover if the expected state is not reached. Each section below combines a concept with ready-to-run commands, expected output, and a decision point. Placeholders like APP_USER, SERVICE_NAME, or BACKUP_DIR must be replaced with values from your environment before execution. Never paste real credentials, tokens, private keys, or production identifiers into a command or script.

Version and Environment Inventory

Before touching a configuration file or restarting a service, you must know exactly what you are running. Start with read-only commands that reveal the operating system, kernel, Bash version, and available tools. This section shows how to collect that inventory in a structured way.

Prerequisites and Assumptions

  • You can open a terminal as a non-root user with sudo rights for administrative commands.
  • You are working on Linux (commands are also relevant for macOS with minor differences).
  • You understand the general layout of /etc, /var, and /home.

Collecting System Facts

Run these commands one at a time and record the output. They do not modify anything.

# Operating system name and version
cat /etc/os-release

# Kernel release
uname -r

# Bash version
bash --version | head -n1

# Current user and groups
id

# Available disk space
 df -h /

# Memory and swap
 free -h

Expected output for cat /etc/os-release on Ubuntu 22.04 includes lines like:

PRETTY_NAME="Ubuntu 22.04.4 LTS"
VERSION_ID="22.04"

On Rocky Linux 9.3, PRETTY_NAME would show "Rocky Linux 9.3 (Blue Onyx)" and VERSION_ID="9.3".

For bash --version, the first line resembles:

GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)

If Bash is older than 4.0 on a system you plan to script heavily, note it; newer syntax like associative arrays may not work.

Identifying Running Services and Ports

Use ss or netstat to see what is listening. These are read-only observations.

# List listening TCP ports with process names (requires sudo for process info)
sudo ss -tulpn

# Alternatively, on older systems:
sudo netstat -tulpn

A typical line from ss -tulpn:

LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))

This tells you SSH is listening on port 22. If you see an unexpected listener on port 8080, investigate before making changes.

Recording Deployment Topology

Write down which services run on which host. A simple command to capture hostname and IP addresses:

hostname
ip -brief address

Sample output:

app-server-01
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.1.25/24 fe80::1/64

Store this inventory in a note or script for later reference. If a service fails, you can compare current state against the known baseline.

Safe Configuration Path

Once you understand the environment, you can make changes. The safe path means: back up the current file, edit with a clear comment, validate syntax, and restart only if verification fails. This section walks through editing a typical service configuration file with full recovery steps.

Back Up Before You Edit

Never edit a configuration file without a timestamped backup. Use cp with a date suffix:

sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-$(date +%Y%m%d-%H%M%S)

For example, on February 3, 2025 at 14:30, the backup file becomes nginx.conf.bak-20250203-143000.

Verify the backup exists:

ls -l /etc/nginx/nginx.conf.bak-*

Expected output shows the original file size and timestamp.

Editing with a Purpose

Use vim, nano, or sed to make the smallest change. Suppose you need to change the worker processes in Nginx from auto to 2 because the server has only 2 CPU cores and you want predictable memory usage.

Before editing, view the current value:

grep -n "worker_processes" /etc/nginx/nginx.conf

Example output:

3:worker_processes auto;

Edit line 3 with sed (or use a visual editor):

sudo sed -i 's/worker_processes auto;/worker_processes 2;/' /etc/nginx/nginx.conf

Validate Syntax Before Applying

For Nginx, run:

sudo nginx -t

Expected success output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If you see an error, revert to the backup immediately:

sudo cp /etc/nginx/nginx.conf.bak-20250203-143000 /etc/nginx/nginx.conf
sudo nginx -t

Reload or Restart Only When Needed

After a successful syntax test, reload Nginx to apply changes without dropping connections:

sudo systemctl reload nginx

If the service fails to reload or the change requires a full restart, use:

sudo systemctl restart nginx

Check status:

systemctl status nginx --no-pager

Look for Active: active (running) in the output. If not active, revert the config and restart again.

Rollback Plan

Always have a rollback plan before you make a change. For the Nginx example:

  1. Backup file path recorded.
  2. Revert command ready: sudo cp /etc/nginx/nginx.conf.bak-20250203-143000 /etc/nginx/nginx.conf
  3. Reload or restart command ready.
  4. Test URL or curl -I http://localhost to confirm.

Verification and Diagnostics

After a change, you must verify the result. Diagnostics involve checking logs, processes, and network behavior to confirm the desired state. This section demonstrates how to check a web service after a configuration change, using Nginx as a concrete example.

Checking Service Status

systemctl is-active nginx

Expected output: active. If it says inactive or failed, investigate with:

systemctl status nginx --no-pager -l
journalctl -u nginx --since "10 minutes ago" --no-pager

The journal output will show error messages. For example, a common mistake is a missing semicolon in the config, which nginx -t would have caught. If you skipped validation, you will see something like:

nginx: [emerg] unexpected end of file, expecting ";" or "}" in /etc/nginx/nginx.conf:42

Verifying Network Response

Use curl to get headers and status code:

curl -I http://localhost

Expected output for success:

HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 03 Feb 2025 14:35:00 GMT
Content-Type: text/html

If you get curl: (7) Failed to connect, check if the service is running and listening:

sudo ss -tulpn | grep :80

Should show a line with nginx and 0.0.0.0:80 or similar.

Following Logs in Real Time

For ongoing issues, tail the access and error logs:

sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log

Send a test request from another terminal and watch the logs update.

Using Diagnostic Commands for Other Services

The same pattern applies to databases, message queues, or application servers. For example, to check if PostgreSQL is accepting connections after an edit to postgresql.conf:

pg_isready -h localhost -p 5432

Expected output: localhost:5432 - accepting connections. If it says no response, check the logs with journalctl -u postgresql and verify listen_addresses in the config.

Failure Modes and Recovery

Failures happen despite careful preparation. This section covers common failure scenarios, how to detect them, and how to recover using the backups and checks you already set up.

Scenario 1: Service Fails to Start After Configuration Change

Symptoms: systemctl start nginx fails, error in journal shows syntax or permission problem.

Immediate recovery:

  1. Revert to the last good backup:
sudo cp /etc/nginx/nginx.conf.bak-20250203-143000 /etc/nginx/nginx.conf
  1. Validate the reverted config:
sudo nginx -t
  1. Start the service:
sudo systemctl start nginx
  1. Verify with curl -I http://localhost.

Scenario 2: Disk Full on Log Partition

Symptoms: Application writes fail, df -h shows 100% use on /var.

Observation:

df -h /var

Example output:

Filesystem Size Used Avail Use% Mounted on
/dev/sda3 20G 20G 0 100% /var

Immediate relief: Find large files:

sudo du -ah /var | sort -rh | head -n 10

If logs are the culprit, you can compress and truncate (after confirming they are not needed for forensics):

sudo tar -czf /tmp/old-logs-$(date +%Y%m%d).tar.gz /var/log/nginx/access.log*
sudo truncate -s 0 /var/log/nginx/access.log

Prevention: Set up logrotate with a policy like:

/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        [ -s /run/nginx.pid ] && kill -USR1 `cat /run/nginx.pid`
    endscript
}

Scenario 3: Out of Memory (OOM) Kill

Symptoms: Process disappears from ps aux, dmesg shows OOM killer message.

Detection:

sudo dmesg -T | grep -i "out of memory"

Example output line:

[Mon Feb 3 14:50:12 2025] Out of memory: Killed process 1234 (node) total-vm:2048000kB, anon-rss:1800000kB, file-rss:0kB, shmem-rss:0kB

Recovery: Restart the service and monitor memory usage:

sudo systemctl restart myapp
free -h

Permanent fix: Adjust the service's memory limit in its systemd unit file under [Service] with MemoryMax=500M, then sudo systemctl daemon-reload and restart.

Operations Checklist

Use this checklist before and after any operational task. It is designed to be printed or kept in a terminal-friendly text file.

Pre-Change Checklist

ItemCommand or ActionExpected ResultOwnerReview Frequency
Record current date and timedateCurrent timestamp, e.g., Mon Feb 3 14:30:00 UTC 2025Operator on dutyEvery change
Identify service and versionnginx -vnginx version: nginx/1.18.0Operator on dutyEvery change
Take configuration backupsudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak-$(date +%Y%m%d-%H%M%S)Backup file present with correct timestampOperator on dutyEvery change
Note current service statussystemctl status nginx --no-pager -lActive: active (running)Operator on dutyEvery change
Define expected outcomeWrite in change tickete.g., "Nginx worker_processes set to 2, service still active"Change requester (named person)Before execution
Prepare rollback commandWrite in change ticketExact revert command readyChange requesterBefore execution

Post-Change Checklist

ItemCommand or ActionExpected ResultOwnerReview Frequency
Validate configurationsudo nginx -tsyntax is ok and test is successfulOperator on dutyImmediately after change
Reload or restart servicesudo systemctl reload nginxNo error outputOperator on dutyImmediately after change
Verify service activesystemctl is-active nginxactiveOperator on dutyImmediately after change
Check logs for errorssudo journalctl -u nginx --since "5 minutes ago" --no-pagerNo new error linesOperator on dutyWithin 5 minutes
Confirm functionalitycurl -I http://localhostHTTP/1.1 200 OKOperator on dutyWithin 5 minutes
Update change ticket with resultDocument in ticket systemClear success or rollback noteChange requesterWithin 15 minutes

Who Owns What

Assign a single accountable owner for each major decision. For example, the Engineering Lead (e.g., Priya Shah) approves configuration changes to production. The on-call operator (e.g., Leo Martinez) executes the change. The change requester (e.g., an application developer, such as Anika Patel) verifies the functional result. These roles and names should be recorded in your team's runbook. Review the runbook monthly, or after any incident, whichever comes first.

Common Pitfalls and How to Avoid Them

Even experienced operators make mistakes. Here are the most frequent Bash and system administration pitfalls, why they happen, and how to prevent or recover from them.

Pitfall 1: Editing Configuration Without a Backup

Why it happens: The change seems trivial, or the operator is under time pressure.

Consequence: If the edit breaks the service, you have no quick way to revert.

How to avoid: Always run the backup command before editing. Make it a habit: sudo cp file file.bak-$(date +%s).

Recovery: If you forget, you might still find a copy in /var/backups or in a configuration management tool like Ansible or Puppet. Otherwise, you must reconstruct the file from memory or documentation.

Pitfall 2: Using rm -rf with Variables That Are Empty

Why it happens: A script uses a variable for a directory path, and the variable is unset or empty because of a typo or logic error.

Example dangerous command:

rm -rf "$TARGET_DIR/"

If TARGET_DIR is empty, this becomes rm -rf / (or a dangerous variant) and can wipe the system.

How to avoid: Always check that the variable is non-empty before using it:

if [ -z "$TARGET_DIR" ]; then
    echo "TARGET_DIR is empty, aborting"
    exit 1
fi
rm -rf "$TARGET_DIR/"

Better yet, use find with -delete and explicit path.

Pitfall 3: Redirecting Output with > When You Meant to Append >>

Why it happens: Typing too quickly or misunderstanding shell redirection.

Consequence: You overwrite an existing file instead of adding to it, losing previous data.

Example: Suppose you want to add a line to a log file but accidentally use >.

How to avoid: Use >> for appending. If you need to write a new file, double-check the filename. You can also set set -o noclobber in your shell to prevent overwriting existing files with >. To override, use >|.

Pitfall 4: Not Quoting Variables in Scripts

Why it happens: Forgetting that filenames or arguments may contain spaces or special characters.

Example:

file=my report.txt
cat $file

This fails because the shell splits $file into my and report.txt.

How to avoid: Always quote variables: cat "$file". Use shellcheck to lint your scripts.

Pitfall 5: Running Commands as Root Without sudo When Required (or Overusing Root)

Why it happens: Convenience or lack of awareness of privilege requirements.

Consequence: Running as root increases the damage from mistakes. Not using sudo when needed results in permission denied errors.

How to avoid: Use a normal user account and sudo only for administrative commands. Configure sudo with specific allowed commands if possible.

Pitfall 6: Misinterpreting Exit Codes

Why it happens: Not checking the exit status of a command, assuming it succeeded.

Example:

sudo systemctl restart nginx
curl -I http://localhost

If the restart failed, the curl will likely fail too, but the operator might only look at the curl output and miss the root cause.

How to avoid: Always check exit codes:

sudo systemctl restart nginx
if [ $? -ne 0 ]; then
    echo "Restart failed, aborting"
    exit 1
fi
curl -I http://localhost

Or use systemctl restart nginx && curl -I http://localhost.

Conclusion

Bash basic commands with practical examples become useful only when each recommendation is version-scoped, observable, and reversible where the technology permits. Copying a command without checking prerequisites and expected output is not an operations procedure; it is a gamble.

As a next step, choose one low-risk verification from the Operations Checklist and execute it in your environment. For example, pick a running service like Nginx, record its current configuration backup, make a harmless comment change, validate, reload, and verify with curl -I http://localhost. Then document the rollback steps. Review the output with a colleague, and store the runbook in your team wiki.

A reliable technical workflow makes failure visible, protects sensitive values, limits changes to the intended resource, and defines recovery verification before an incident forces the decision. Practice these commands in a staging environment first, and you will be ready when production demands calm, competent action.

Related Research

Article Quality Score

Reader usefulness 100%
  • check_circle Reader-ready guide
  • check_circle Practical examples included
  • check_circle Clean SEO article URL