· 6 min read

Bash Shell Commands for System Administration: A Comprehensive Guide

A practical, in-depth guide to the Bash commands and workflows every system administrator should know - from user and file management to monitoring, networking, service control, backups, and safe automation.

Introduction

Bash is the workhorse shell for most Linux/Unix system administrators. Knowing a compact set of commands, options, and idioms lets you inspect systems quickly, automate repetitive tasks, and troubleshoot effectively. This guide collects essential Bash commands and patterns for system administration, with clear examples, safety tips, and references to authoritative docs.

Table of contents

  • Essentials: navigation, file ops, text processing
  • Users and permissions
  • Processes and job control
  • System monitoring and performance
  • Networking and connectivity
  • Package & service management
  • Logs, journal, and troubleshooting
  • Scheduling & automation (cron, systemd timers)
  • Backups and storage management
  • Remote administration (SSH, tunnels)
  • Useful scripting snippets and best practices
  • Safety, debugging, and final cheatsheet

Essentials: navigation, file operations, and text processing

Basic navigation and listing:

cd /var/log            # change directory
pwd                    # print working directory
ls -lha /etc           # human-readable, all files, long listing
tree -a /usr/local/bin  # if tree installed - recursive, visual

Find files and recent changes:

find / -type f -name "*.conf" 2>/dev/null
find /var/log -mtime -7       # files modified in last 7 days

Inspect files and search inside them:

cat /etc/os-release
less /var/log/syslog
grep -i "error" /var/log/syslog | tail -n 50
zgrep "exception" /var/log/*.gz

Useful text tools:

  • grep - search lines; use -R for recursive
  • awk - field processing and quick reporting
  • sed - stream editing (substitute, delete)
  • cut/sort/uniq - column slicing and aggregation

Examples:

# Show top 10 most common IPs in access log
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head

# Replace 127.0.0.1 with localhost in a file (in-place backup)
sed -i.bak 's/127\.0\.0\.1/localhost/g' /etc/myapp/config

Reference: GNU Coreutils manual.

Users, groups, and permissions

User and group management (requires root or sudo):

# Add a user with home and default shell
sudo useradd -m -s /bin/bash alice
sudo passwd alice

# Add to group
sudo usermod -aG sudo alice

# Delete user and remove home
sudo userdel -r alice

File ownership and permissions:

# Set ownership to user:group
sudo chown alice:developers /srv/app -R

# Permissions: read/write/execute for owner, read for group, none for others
chmod 640 /etc/myapp/secret.conf
chmod +x /usr/local/bin/deploy.sh

# Symbolic vs numeric modes
chmod u+rwx,g+rx,o-rwx file.txt
chmod 750 file.txt

Advanced ACLs and umask:

# View/set POSIX ACLs
getfacl /srv/shared
setfacl -m u:alice:rwx /srv/shared

# Default new file permissions (umask: inverse of permissions)
ulimit -a
umask 0027   # new files: 750-ish

Security reference: chmod man page.

Processes and job control

Inspect processes:

ps aux | grep myservice
ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head

# Modern alternative: pgrep and pkill
pgrep -a nginx
pkill -HUP nginx

Interactive tools:

  • top - basic live view
  • htop - interactive, tree view (recommended)
  • iotop - IO usage per process

Control and priorities:

# Start detached with nohup
nohup ./long_job.sh > /var/log/long_job.log 2>&1 &

# Nice and renice to adjust CPU priority
nice -n 10 ./backup.sh
sudo renice -n 5 -p 1234

# Kill politely then force
kill 1234           # SIGTERM
kill -9 1234        # SIGKILL (last resort)

Process docs: procps-ng (ps, top).

System monitoring and performance

Quick health checks:

uptime            # load averages
vmstat 1 5        # memory, swaps, CPU per second
free -h           # memory usage human-readable

Disk usage and inodes:

df -h /            # filesystem usage
du -sh /var/log/*   # directory sizes
stat -f /home       # filesystem stats

I/O and latency:

iostat -x 1 3      # detailed device IO stats
iotop -o            # show only processes doing IO

Network-related monitoring:

ss -tulpen         # list sockets (replacement for netstat)
netstat -s         # protocol statistics

# Real-time packet capture (requires tcpdump)
sudo tcpdump -n -i eth0 port 22

Networking and connectivity

Basic network inspection:

ip addr show                # interfaces and IPs
ip route show               # routing table
ip -s link show             # NIC statistics

# Bring interface up/down
sudo ip link set dev eth0 up
sudo ip link set dev eth0 down

Connectivity testing:

ping -c 4 8.8.8.8
traceroute -n example.com
curl -I https://example.com

# DNS and service discovery
dig A example.com +short

Reference: iproute2 documentation.

Package & service management

Package managers vary by distro. Common examples:

# Debian/Ubuntu
sudo apt update && sudo apt upgrade -y
apt-cache policy nginx

# RHEL/CentOS/Fedora
sudo dnf install -y httpd
sudo yum history

System services (systemd):

# Manage services
sudo systemctl start nginx
sudo systemctl enable nginx    # start on boot
sudo systemctl status nginx
sudo systemctl restart nginx

# View service logs via journal
sudo journalctl -u nginx.service --since "1 hour ago"

Systemd docs: systemd homepage.

Logs, journaling, and troubleshooting

Traditional logs in /var/log and systemd’s journal are your primary troubleshooting sources.

# Search classic logs
sudo less /var/log/syslog
sudo tail -n 200 /var/log/nginx/error.log

# Systemd journal
sudo journalctl -b         # logs since last boot
sudo journalctl -u sshd    # logs for unit
sudo journalctl -f         # follow live

Tips:

  • Use timestamps and —since/—until with journalctl for targeted searches.
  • Rotate logs with logrotate; check /etc/logrotate.d/.

Scheduling & automation

Cron (classic):

# Edit root's crontab
sudo crontab -e
# Example: daily backup at 2:30am
30 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

Systemd timers (modern alternative) offer more control and logging:

# /etc/systemd/system/daily-backup.service
[Unit]
Description=Daily backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh

# /etc/systemd/system/daily-backup.timer
[Unit]
Description=Run daily-backup daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Enable timer:

sudo systemctl enable --now daily-backup.timer

Backups and storage management

Reliable commands:

  • rsync - incremental backups and mirroring
  • tar - archiving and compression
  • dd - low-level copying (disk images)

Examples:

# Incremental local backup with rsync
rsync -av --delete --link-dest=/backups/prev/ /srv/app/ /backups/today/

# Compressed archive of /etc
tar -czf /tmp/etc-$(date +%F).tar.gz /etc

# Copy entire disk to image (careful!)
sudo dd if=/dev/sda of=/mnt/backup/sda.img bs=4M status=progress

Use checksums to verify backups (md5sum/sha256sum). Consider encryption for offsite backups (gpg, borg).

Rsync reference: rsync documentation.

Remote administration (SSH, tunnels, port forwarding)

SSH basics:

# Connect with identity file
ssh -i ~/.ssh/id_rsa alice@server.example.com

# Copy files
scp file.tar.gz alice@server:/tmp/
rsync -avz -e "ssh -i ~/.ssh/id_rsa" ./dir alice@server:/srv/

Tunnels and forwarding:

# Local port forward: access remote DB locally
ssh -L 5432:localhost:5432 alice@db.example.com

# Reverse tunnel: expose local service to remote host
ssh -R 2222:localhost:22 alice@remote.example.com

Manage authorized keys and use ~/.ssh/config for convenience and security.

OpenSSH docs: OpenSSH.

Useful scripting snippets and best practices

Small automation patterns:

  • Always set strict mode at top of scripts:
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
  • Logging and dry-run support:
DRY_RUN=${DRY_RUN:-false}
log() { echo "$(date --iso-8601=seconds) - $*"; }
run() { if [ "$DRY_RUN" = true ]; then echo "DRY: $*"; else "$@"; fi }

run rsync -av /src /dst
  • Exit codes: use meaningful exit codes; trap signals for cleanup
trap 'rm -f "$TMPFILE"; exit 1' INT TERM

Safety, debugging, and best practices

  • Use sudo and principle of least privilege; configure /etc/sudoers carefully via visudo.
  • Test destructive commands (rm, dd, fdisk) on non-production or with dry-run flags.
  • Use —no-preserve-root and similar options carefully; never run destructive commands as root without understanding.
  • Keep configuration in version control (git) and provide rollback procedures.
  • Monitor using alerting (Prometheus, Nagios, etc.) - logs alone are not enough.
  • Automate idempotently: scripts should be safe to re-run.

Quick cheatsheet (common commands)

  • File and text: ls, cp, mv, rm, find, grep, awk, sed, cut
  • Users & perms: useradd, userdel, usermod, chown, chmod, getfacl/setfacl
  • Processes: ps, top, htop, pgrep, pkill, nice, renice
  • Disk & FS: df, du, lsblk, fdisk, mkfs, mount, umount
  • Network: ip, ss, netstat, traceroute, dig, curl, tcpdump
  • Services & packages: systemctl, journalctl, apt/dnf/yum, rpm, dpkg
  • Backup & transfer: rsync, tar, scp, sftp

References

Closing

This guide focuses on practical Bash commands and patterns that make system administration reliable and faster. Pair these commands with monitoring, configuration management (Ansible/Chef/Puppet), and solid testing practices to manage infrastructure at scale.

Back to Blog

Related Posts

View All Posts »