bigonotes
LinuxProcesses and Services

Processes, Disks and Remote Access

Inspect and signal processes, run jobs in the background, find zombies, check disk space, archive files and work over SSH.

8 min readLast updated

When a server misbehaves, the first questions are usually: what is running, what is using the CPU or memory, and is the disk full? This note covers the commands that answer them, plus archiving files and working on a remote machine over SSH. For what a process is inside the kernel, see Processes vs Threads.

Listing processes with ps#

A process is a running instance of a program. Each one has a PID (process ID) and a PPID, the PID of the parent that started it. ps prints a snapshot of processes, and its flags decide which ones you see.

Command Shows
ps Your processes in the current terminal
ps aux Every process, in a user-oriented format
ps -ef Every process, with PPID and the full command
ps -o pid,ppid,stat,cmd -p 1234 Chosen columns for one PID

The aux flags look cryptic, so here's what they mean. In ps aux, a means all users, u adds user-oriented columns, and x includes processes with no terminal, such as daemons.

$ ps -ef | head -3
UID    PID  PPID  C STIME TTY      TIME     CMD
root     1     0  0 09:00 ?        00:00:02 /sbin/init
alice 4211  4210  0 09:12 pts/0    00:00:00 -bash

Common columns#

The output is a table, and column names vary a little between ps formats. These are the ones you read most.

Column Meaning
UID / USER Who owns the process
PID / PPID Process ID and parent process ID
%CPU / %MEM Share of CPU and RAM in use
VSZ Virtual memory size: all memory the process has mapped
RSS Resident set size: physical RAM in use now, in KB
TTY Controlling terminal (? means none, such as a daemon)
STAT / S Process state (see below)
TIME Total CPU time used so far
NI Nice value: higher means lower priority

VSZ is usually much larger than RSS, because most mapped memory is never loaded into RAM. See Virtual Memory for why.

Process states#

The STAT column holds a letter that tells you what the process is doing.

Letter State
R Running or ready to run
S Sleeping, waiting for an event (most processes)
D Uninterruptible sleep, usually waiting on disk or network I/O
T Stopped, for example by Ctrl+Z
Z Zombie: finished, but the parent hasn't collected its exit status

Live view with top#

ps is a snapshot. When you need to watch a problem as it happens, use top, which refreshes a sorted process list every few seconds. The header shows load average, CPU use and memory. The table shows PID, USER, %CPU, %MEM, TIME+ and COMMAND.

Key Action
P / M Sort by CPU / by memory
k Kill a process (asks for the PID)
h Help
q Quit

Many systems also have htop, a friendlier version with colors and mouse support.

Background jobs#

Not every process you care about is a server daemon. Often it's a command you started yourself, and the shell can run several of those from one terminal. A foreground job owns the terminal until it ends. A background job runs while you keep typing.

Action How
Start in the background long-task &
Pause the foreground job Ctrl+Z
List jobs in this shell jobs
Resume a job in the background bg %1
Bring a job to the foreground fg %1

%1 is a job number from jobs, not a PID.

Signals and kill#

Sooner or later you'll need to stop a process, from top, from a job list or by PID. kill sends a signal to a process. Despite the name, many signals don't end the process.

Signal Number Meaning
SIGTERM 15 Ask the process to exit. It can clean up first. Default for kill.
SIGKILL 9 End it at once. It can't be caught, so no cleanup runs.
SIGINT 2 Interrupt. Sent by Ctrl+C.
SIGHUP 1 Hangup: the terminal closed. Many daemons treat it as "reload your config".
SIGTSTP 20 Stop from the terminal. Sent by Ctrl+Z.

Signal numbers above are for x86 and ARM Linux. Names are portable, so prefer them.

kill 1234             # SIGTERM: polite
kill -HUP 1234        # reload config, for daemons that support it
kill -9 1234          # SIGKILL: last resort
pkill -f "python worker.py"   # signal by command line

Send SIGTERM first and give the process a few seconds. Jump to SIGKILL only if it hangs. SIGKILL skips cleanup, so it can leave temp files, locks or half-written data behind.

nohup: survive a closed terminal#

SIGHUP from the table above causes a common surprise. When you close a terminal or lose an SSH session, the shell sends SIGHUP to its jobs, and most exit. nohup makes a command ignore that signal.

nohup ./backup.sh > backup.log 2>&1 &

Without a redirect, nohup writes output to nohup.out. For anything long-lived, a systemd service or a terminal multiplexer such as tmux is a safer choice. See systemd.

Zombie processes#

You saw the Z state earlier. A zombie is a child process that has finished but still has an entry in the process table. The entry keeps the exit status until the parent reads it with wait(). A parent that never calls wait() leaves zombies behind.

Zombies use no CPU and almost no memory, but each one holds a PID. You can't kill one, because it's already dead. Fix or restart the parent. When a parent exits, PID 1 adopts its children and reaps any zombies.

# Find zombies and their parents
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /^Z/'

ps aux | grep Z is a common shortcut, but it also matches any line that contains a capital Z.

shutdown#

Sometimes the fix for a stuck system is a reboot. shutdown powers off or reboots the machine and warns logged-in users first.

sudo shutdown -h now                      # power off now
sudo shutdown -r +5 "Rebooting for patch" # reboot in 5 minutes
sudo shutdown -c                          # cancel a scheduled shutdown

Disk space: du and df#

The last question from the opening is the disk. Two commands answer different parts of it. df asks "how full is each filesystem?" du asks "what is using the space?"

Command Shows
df -h Size, used and free space per mounted filesystem
df -T Adds the filesystem type (ext4, xfs)
df -i Inode use instead of block use
du -sh /var/log Total size of one directory
du -h --max-depth=1 /var Size of each subdirectory
$ df -h /
Filesystem  Size  Used Avail Use% Mounted on
/dev/sda1    50G   21G   27G  44% /

A filesystem can run out of inodes (the fixed number of entries that store each file's metadata) before it runs out of bytes. This happens with millions of tiny files. Writes then fail with "No space left on device" while df -h still shows free space. Check df -i.

Archives: tar and zip#

Once you find what's filling a disk, you'll often want to bundle it up to move or back it up. tar bundles many files into one archive. It doesn't compress unless you add a compression flag.

Flag Meaning
-c Create an archive
-x Extract an archive
-t List contents
-v Verbose: print each file
-f The archive file name (put it last in the flag group)
-z Compress or decompress with gzip
tar -czvf site.tar.gz /srv/www       # create, gzip-compressed
tar -tzf site.tar.gz                 # list contents
tar -xzvf site.tar.gz -C /tmp/site   # extract into a directory

zip creates compressed .zip files, common when you share with Windows users. It needs -r to include a directory's contents.

zip -r project.zip project/
unzip -l project.zip     # list without extracting
unzip project.zip

Remote access: ssh and scp#

Everything above assumes you're already on the server. In practice you reach it from your laptop. ssh opens an encrypted shell on another machine. scp copies files over the same encrypted connection.

ssh deploy@203.0.113.10                  # log in as user deploy
ssh -i ~/.ssh/id_ed25519 deploy@203.0.113.10
ssh deploy@203.0.113.10 'df -h /'        # run one command and exit

scp report.txt deploy@203.0.113.10:~/    # local to remote
scp deploy@203.0.113.10:/var/log/app.log .   # remote to local
scp -r site/ deploy@203.0.113.10:/srv/www/   # a whole directory

Use SSH keys instead of passwords. Create a key pair with ssh-keygen -t ed25519 and copy the public key to the server with ssh-copy-id. Keep the private key at mode 600 (see Permissions, Ownership and sudo).

Reading the manual#

When you forget a flag for any command in this note, the answer is already on the machine. man <command> opens the manual page for a command: its options, behavior and often examples. Press / to search, n for the next match and q to quit. Pages are grouped into numbered sections, so man 5 crontab asks for the config-file page, not the command.

Key takeaways#

  • ps aux or ps -ef for a snapshot, top for a live view. RSS is real RAM, VSZ is mapped memory.
  • &, Ctrl+Z, jobs, bg and fg manage jobs in one shell.
  • kill sends SIGTERM by default. Use SIGKILL (9) only as a last resort. SIGHUP often means "reload".
  • Zombies are dead children whose parent has not called wait(). Fix the parent.
  • df shows how full a filesystem is; du shows what fills it. Check df -i for inode exhaustion.
  • tar -czf to archive, ssh and scp with keys for remote work.
Revision notes · 2 min

Core idea#

Inspect processes with ps and top, control them with signals, check disks with df and du, and work remotely with ssh and scp.

Key points#

  • ps aux or ps -ef lists every process. top gives a live, sorted view.
  • RSS is physical RAM in use. VSZ is all mapped memory, usually much larger.
  • States: R running, S sleeping, D waiting on I/O, T stopped, Z zombie.
  • Jobs: cmd &, Ctrl+Z, jobs, bg %1, fg %1. %1 is a job number, not a PID.
  • nohup cmd & survives a closed terminal. Output goes to nohup.out without a redirect.
  • tar -czvf creates, -tzf lists, -xzvf extracts. zip -r for directories.
  • ssh user@host, scp file user@host:path. Use keys from ssh-keygen -t ed25519.

Signals#

Signal Number Meaning
SIGTERM 15 Polite exit, allows cleanup; kill default
SIGKILL 9 Immediate, cannot be caught
SIGINT 2 Ctrl+C
SIGHUP 1 Hangup; daemons often reload config

du vs df#

Command Answers
df -h How full is each filesystem?
du -sh dir What is using the space?
df -i Are inodes running out?

Pitfalls#

  • Send SIGTERM first. SIGKILL skips cleanup and can leave locks or half-written data.
  • You cannot kill a zombie. Fix or restart the parent, which must call wait().
  • Millions of tiny files can exhaust inodes while df -h shows free space.
  • ps aux | grep Z matches any line with a capital Z. Filter on the state column.

Say it in an interview#

  • "I check top, then df -h and df -i, then the service logs."
  • "SIGTERM first, SIGKILL only if it hangs."

Found a mistake? Email ask@bigonotes.com

Further reading#