Gestione dei processi
PID e kill
Ogni programma che viene lanciato in una sessione al terminale viene identificato dal kernel come un processo, con la sua allocazione di risorse (come accesso al disco, memoria RAM, cicli di CPU, ecc.).
In particolare, ogni processo viene identificato con un numero intero,
detto PID (Process ID). È possibile vedere una lista di tutti i
processi attivi sul sistema tramite il comando ps -e
;
sshd
.
Suggerimento: non è necessario scorrere
manualmente la lista per trovarlo, ma si può usare (ad esempio) il
comando grep
visto la scorsa volta.
Nel caso si voglia terminare un programma, si può usare il comando
kill
, oppure killall
. Il primo prende come
argomento il numero di un processo, il secondo un nome (oppure anche
un utente, usando il flag -u
). Il secondo comando può essere
più semplice da usare per evitare di dover chiamare ps
solo
per trovare il PID del processo desiderato.
kill
per terminare
il processo sshd
, il cui PID è stato determinato
nell'esercizio precedente.
Il comando kill
permette di spedire diversi segnali
ai processi. Quello di default è chiamato SIGTERM
e
chiede "gentilmente" ad un processo di uscire. Al processo si
permette di svolgere delle operazioni prima di farlo (come ad
esempio di salvare i file aperti). Tuttavia, questo permette anche
al processo anche di ignorare la richiesta.
Altri segnali non vengono invece comunicati al processo, ma vengono
eseguiti direttamente. Un esempio è il segnale SIGKILL
,
che uccide un processo "senza ammettere risposta".
Si può scegliere un tipo diverso di segnale con l'opzione
(ad esempio)
kill -SIGKILL
, o anche direttamente con il codice
intero che identifica il segnale, come kill -9
. Si veda
il manuale di kill
per ulteriori dettagli.
bash
, che è anche il nome del processo. Si
utilizzi per kill
per ucciderlo, e terminare in modo
immediato la propria sessione. Si provi sia con kill senza
opzioni, sia con kill -SIGKILL
.
Una curiosità: i processi vengono gestiti in modo gerarchico: al boot
del sistema viene avviato un processo speciale, detto init, con PID settato a 1.
Questo avvierà poi vari processi, come ad esempio l'interfaccia grafica, che
a loro volta avvieranno processi, e così via. È possibile visualizzare questa
struttura gerarchica di processi tramite il comando pstree
.
Return code
Quando un processo termina, ritorna un interno che può essere usato per determinare se il programma ha raggiunto il suo scopo oppure no, e se ha incontrato un errore. L'interpretazione di questo intero è strettamente legata al software, ed ognuno ha le sue convenioni. Tuttavia, normalmente si considera l'intero 0 come "successo", e altri numeri interi come codici di un errore.
Per controllare il codice di errore dell'ultimo programma che è terminato,
si può stampare il valore della variabile speciale $?
; vedremo
poi il significato del simbolo $
nel dettaglio. Il valore
della variabile può essere stampato con echo
.
grep
per capire come interpretare
il codice ritornato da grep. Si generino due esempi, uno in cui il codice
ritornato sia zero, ed uno in cui invece sia diverso da zero.
Mettere in pausa un processo
Fra i segnali menzionati in precedenza, c'è una coppia che permette
di mettere in pausa e riprendere l'esecuzione di un programma. Questi
sono i segnali SIGSTOP
e SIGCONT
.
- Sul primo terminale lanciare il comando
yes
; questo è un comando che non fa altro che stampare la stringay
all'infinito, fino a che non viene interrotto (riuscite ad immaginare a cosa potrebbe servire un comando del genere?). - Da un secondo terminale, si provi a mettere in pausa il comando lanciando i segnali SIGSTOP e SIGCONT.
CTRL+Z
per spedire
un segnale SIGSTOP
al processo corrente. È poi possibile
farlo continuare con il comando fg
, oppure continuare
in background con il comando bg
.
Variabili d'ambiente
Come in ogni linguaggio di programmazione, anche in bash è possibile definire delle variabili. Alcune di queste sono già definite con dei valori di default quando effettuiamo il login, e vengono "eredidate" dai processi che lanciamo dal terminale.
In bash le variabili si riconoscono perché preduto da simbolo
del dollaro. Ad esempio, $HOME
è una delle variabili
già definite al momento del login. Ogni apparizione della variabile
in un comando viene sostituito con il suo valore, a meno di poche
eccezioni, come mostrato dal seguente esempio.
$HOME
con il seguente comando:
$ echo $HOMECosa succede se si racchiude la variabile
$HOME
fra
virgolette singole o doppie? Potete ipotizzare quale sia la differenze
fra questi due tipi di apici?
Possiamo definire altre variabili nella sessione corrente con la sintassi:
$ MIAVARIABILE="prova"L'uso delle virgolette non è obbligatorio, ma è consigliabile per evitare problemi con la presenza di spazi. Tuttavia, una variabile così definita non verrebbe passata ad un sottoprocesso.
bash
.
Provare a stampare il valore della variabile. Cosa succede?
Si provi ad uscire dalla sessione annidata, esportare la variabile
con il comando
export MIAVARIABILE
, e ripetere l'esperimento. Il comportamento
è cambiato?
env
.