Prima di terminare o di correggere qualcosa bisogna vederlo. Per l’esame bastano cinque strumenti: ps scatta una fotografia, top gira il filmato, free e uptime raccontano lo stato della macchina, pgrep trova un PID e watch ripete qualunque comando finché non ti stufi.

ps: un comando, tre sintassi

ps accetta tre stili di opzioni: BSD senza trattino, UNIX con un trattino, GNU con due. Non sono sinonimi, e la stessa lettera cambia significato a seconda del trattino.

$ ps aux        # BSD: tutti i processi, anche senza terminale, formato utente
$ ps -ef        # UNIX: tutti i processi, formato completo
$ ps u          # BSD: formato orientato all'utente
$ ps -u carol   # UNIX: i processi dell'utente carol

ps aux e ps -ef sono le due righe da saper digitare a memoria: senza opzioni, ps mostra soltanto i processi della tua shell. Le colonne di ps aux sono USER, PID, %CPU, %MEM, VSZ (memoria virtuale), RSS (RAM residente), TTY, STAT, START, TIME (tempo di CPU accumulato) e COMMAND.

STAT   R in esecuzione o in coda    S sleep interrompibile
       D sleep non interrompibile   T fermato       Z zombie
       + primo piano                s leader di sessione

Un processo in stato D non risponde nemmeno a SIGKILL finché l’operazione di I/O non si sblocca; uno zombie ha già terminato e sparirà solo quando il padre ne raccoglie lo stato di uscita, quindi ucciderlo è inutile.

Selezionare e ordinare

L’obiettivo d’esame parla esplicitamente di scegliere e ordinare i processi da mostrare, e si fa così:

$ ps -eo pid,user,%cpu,%mem,comm --sort=-%mem | head -5
$ ps -C sshd
$ ps -ejH

-e prende tutti i processi, -o decide le colonne, --sort le ordina (il segno meno inverte l’ordine), -C seleziona per nome del comando. Per vedere le parentele c’è ps -ejH, oppure ps axjf in stile BSD, oppure pstree.

top: la stessa scena, in movimento

top si aggiorna da solo, per default ogni 3 secondi, ed è interattivo. I tasti che contano: M ordina per memoria, P per CPU, N per PID, T per tempo di esecuzione, R inverte l’ordine, k invia un segnale a un PID, r cambia la priorità, u filtra per utente, c mostra la riga di comando completa, V disegna l’albero, W salva la configurazione in ~/.toprc, h è l’aiuto e q esce. Per usarlo dentro uno script o su un file serve la modalità batch:

$ top -b -n 1 > istantanea.txt
$ top -u www-data

Le righe di riepilogo ripetono uptime e free, più Tasks (quanti processi in esecuzione, dormienti, fermati, zombie) e %Cpu(s): us utente, sy kernel, id inattivo, wa in attesa del disco, st tempo rubato dall’host in una macchina virtuale. Un wa alto indica un problema di I/O, non di CPU. htop è più comodo ma non è quello che l’esame chiede.

free e uptime

$ free -h
              total   used   free  shared  buff/cache  available
Mem:           15Gi  2,0Gi   11Gi   105Mi       2,3Gi        13Gi
Swap:         2,0Gi     0B  2,0Gi

-h rende leggibili le cifre, -m le esprime in MiB, -s 5 ripete la misura ogni 5 secondi. Vale total = used + free + buff/cache, ma la colonna da guardare è available, non free: la cache viene restituita alle applicazioni appena serve, quindi una free bassa non è un allarme. Le versioni più vecchie del comando mostravano al suo posto una riga -/+ buffers/cache.

uptime dà in una riga l’ora, da quanto tempo la macchina è accesa, quanti utenti sono collegati e il load average a 1, 5 e 15 minuti, cioè il numero medio di processi pronti a girare o in attesa di I/O. Va sempre rapportato al numero di CPU: 4,00 su quattro core è pieno carico, su un core è una coda.

pgrep e watch

$ pgrep -l sshd
$ pgrep -a -u root nginx
$ pgrep -f 'python3 backup.py'
$ watch -n 5 -d free -h
$ watch 'ps -eo pid,comm,%cpu --sort=-%cpu | head -5'

pgrep stampa i PID che corrispondono a un nome: -l aggiunge il nome, -a la riga di comando intera, -u filtra per utente, -c conta e basta. La trappola: senza -f il confronto avviene solo sui primi 15 caratteri del nome del processo, per cui un demone dal nome lungo può sfuggirti. Il vecchio pidof fa una cosa simile pretendendo il nome esatto.

watch riesegue un comando ogni 2 secondi (-n cambia l’intervallo, -d evidenzia le differenze fra un giro e l’altro, -t toglie l’intestazione). Se la riga contiene una pipe gli apici sono obbligatori, altrimenti la pipe la interpreta la shell e watch vede solo il primo comando.