Advanced Linux Command-Line Strategies and Techniques

A collection of power-user techniques for anyone comfortable with the basics who wants to level up their command-line workflow.

1. Process Substitution & Pipelines

Process substitution lets you treat the output of a command as if it were a file, which is incredibly useful for comparisons and multi-way piping.

Compare two command outputs directly:

diff <(ls dir1) <(ls dir2)

This compares the directory listings without ever writing a temp file to disk.

Send one stream to multiple consumers:

cat access.log | tee >(grep "ERROR" > errors.log) >(grep "WARN" > warnings.log) > /dev/null

One log file gets split into two filtered files in a single pass.

2. xargs with Parallelism

xargs turns a list of items into arguments for another command โ€” and can run them in parallel.

find . -name "*.log" -print0 | xargs -0 -P4 -I{} gzip {}
  • -P4 runs up to 4 jobs concurrently
  • -print0 / -0 null-delimits filenames so spaces and special characters don’t break things

This can turn a slow serial batch job into one that finishes in a fraction of the time on a multi-core machine.

3. awk as a Mini-Language

awk isn’t just for printing columns โ€” it’s a full text-processing language with variables, conditionals, and state.

Basic field extraction:

awk -F: '{print $1, $3}' /etc/passwd

Stateful log analysis (running total of bytes served):

awk '{total += $10} END {print "Total bytes:", total}' access.log

Pattern-triggered action:

awk '/ERROR/{count++} END {print "Errors found:", count}' app.log
4. Advanced journalctl Usage

journalctl replaces flat log files on systemd systems and supports rich filtering.

Live-tail a specific service:

journalctl -u sshd --since "1 hour ago" -f

Only errors from the current boot:

journalctl -p err -b

Filter by time range across all units:

journalctl --since "2026-09-01" --until "2026-09-05"
5. strace / ltrace for Troubleshooting

When a program misbehaves and you need to know exactly what it’s doing under the hood:

strace -f -e trace=network ./mybinary
  • -f follows child processes
  • -e trace=network narrows the noise down to just network-related syscalls (connect, send, recv, etc.)

ltrace does the same for library calls, which is useful when you suspect the issue is in a shared library rather than the kernel interface.

6. rsync Beyond Basic Copying

Safe dry-run before a destructive mirror:

rsync -avz --delete --dry-run /source/ /destination/

Nothing is copied or deleted โ€” you just see what would happen.

Space-efficient incremental backups:

rsync -a --link-dest=/backups/previous /source/ /backups/current/

Unchanged files are hardlinked to the previous backup instead of duplicated, so each snapshot only costs disk space for what actually changed.

7. Job Control, disown, and Terminal Multiplexers

Starting a long-running job and walking away from the terminal:

nohup ./long_job.sh > output.log 2>&1 &
disown

Better yet, run it inside tmux or screen so you can reattach later and see live output:

tmux new -s longjob
./long_job.sh
# detach with Ctrl+b, d โ€” reattach anytime with: tmux attach -t longjob
8. systemd Timers Instead of Cron

Timers integrate with the rest of systemd, giving you built-in logging and dependency management that cron lacks.

Example timer unit (/etc/systemd/system/backup.timer):

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Paired with a backup.service unit, you get automatic retries, journalctl logging, and the ability to require other services to be running first โ€” all things a plain crontab entry can’t do.

9. Bash Parameter Expansion Tricks

These reduce how often you need to reach for sed or awk for simple string manipulation:

# Default value if variable is unset
echo "${NAME:-anonymous}"

# Search and replace within a variable
path="/home/user/file.txt"
echo "${path//\//_}"   # /home/user/file.txt -> _home_user_file.txt

# Array length
files=(*.txt)
echo "${#files[@]}"
10. ss Over netstat

netstat is deprecated on most modern distros in favor of ss, which is faster and pulls directly from kernel data structures.

ss -tulpn
  • -t TCP, -u UDP, -l listening sockets only, -p show the owning process, -n numeric (skip DNS lookups)

Have a favorite command-line trick not covered here? Reach out to the group โ€” this section will keep growing.