Bash Gestione del lavoro


Esempio

Creazione di posti di lavoro

Per creare un lavoro, aggiungi un singolo & dopo il comando:

$ sleep 10 &
[1] 20024

Puoi anche fare un processo in esecuzione un lavoro premendo Ctrl + z :

$ sleep 10
^Z
[1]+  Stopped                 sleep 10

Sfondo e primo piano un processo

Per portare il processo in primo piano, il comando fg viene utilizzato insieme a %

$ sleep 10 &
[1] 20024

$ fg %1
sleep 10

Ora puoi interagire con il processo. Per riportarlo sullo sfondo puoi usare il comando bg . A causa della sessione del terminale occupata, è necessario interrompere prima il processo premendo Ctrl + z .

$ sleep 10
^Z
[1]+  Stopped              sleep 10

$ bg %1
[1]+ sleep 10 &

A causa della pigrizia di alcuni programmatori, tutti questi comandi funzionano anche con una singola % se esiste un solo processo o per il primo processo nell'elenco. Per esempio:

$ sleep 10 &
[1] 20024

$ fg %        # to bring a process to foreground 'fg %' is also working.
sleep 10

o semplicemente

$ %           # laziness knows no boundaries, '%' is also working.
sleep 10

Inoltre, semplicemente digitando fg o bg senza alcun argomento si gestisce l'ultimo lavoro:

$ sleep 20 &
$ sleep 10 &
$ fg
sleep 10
^C
$ fg
sleep 20

Uccisione di lavori in corso

$ sleep 10 &
[1] 20024

$ kill %1
[1]+  Terminated              sleep 10

Il processo di sospensione viene eseguito in background con ID processo (pid) 20024 e numero di lavoro 1 . Per fare riferimento al processo, è possibile utilizzare il pid o il numero del lavoro. Se si utilizza il numero del lavoro, è necessario prefisso con % . Il segnale di kill predefinito inviato da kill è SIGTERM , che consente al processo di destinazione di uscire con garbo.

Di seguito sono mostrati alcuni segnali di uccisione comuni. Per vedere un elenco completo, esegui kill -l .

Nome del segnale Valore del segnale Effetto
SIGHUP 1 Appendere
SIGINT 2 Interrompere dalla tastiera
SIGKILL 9 Uccidere il segnale
SIGTERM 15 Segnale di terminazione

Avvia e uccide processi specifici

Probabilmente il modo più semplice per uccidere un processo in esecuzione è selezionarlo attraverso il nome del processo come nell'esempio seguente usando il comando pkill come

pkill -f test.py

(o) un modo più a prova di pazzo usando pgrep per cercare l'id-processo vero e proprio

kill $(pgrep -f 'python test.py')

Lo stesso risultato può essere ottenuto usando grep su ps -ef | grep name_of_process quindi uccide il processo associato al pid risultante (id processo). Selezionare un processo usando il suo nome è conveniente in un ambiente di test, ma può essere molto pericoloso quando lo script viene utilizzato in produzione: è praticamente impossibile essere sicuri che il nome corrisponda al processo che si desidera effettivamente uccidere. In questi casi, il seguente approccio è molto più sicuro.

Inizia lo script che alla fine verrà ucciso con il seguente approccio. Supponiamo che il comando che vuoi eseguire ed eventualmente uccidere sia python test.py

#!/bin/bash

if [[ ! -e /tmp/test.py.pid ]]; then   # Check if the file already exists
    python test.py &                   #+and if so do not run another process.
    echo $! > /tmp/test.py.pid
else
    echo -n "ERROR: The process is already running with pid "
    cat /tmp/test.py.pid
    echo
fi

Questo creerà un file nella /tmp contenente il pid del processo python test.py Se il file esiste già, assumiamo che il comando sia già in esecuzione e lo script restituisca un errore.

Quindi, quando vuoi ucciderlo usa il seguente script:

#!/bin/bash

if [[ -e /tmp/test.py.pid ]]; then   # If the file do not exists, then the
    kill `cat /tmp/test.py.pid`      #+the process is not running. Useless
    rm /tmp/test.py.pid              #+trying to kill it.
else
    echo "test.py is not running"
fi

questo ucciderà esattamente il processo associato al tuo comando, senza fare affidamento su alcuna informazione volatile (come la stringa usata per eseguire il comando). Anche in questo caso se il file non esiste, lo script presuppone che si desideri terminare un processo non in esecuzione.

Questo ultimo esempio può essere facilmente migliorato per l'esecuzione dello stesso comando più volte (aggiungendo il file pid invece di sovrascriverlo, ad esempio) e per gestire i casi in cui il processo muore prima di essere ucciso.