Da qualche tempo, assieme ad alcuni miei studenti, stiamo lavorando su un progetto legato alla virtualizzazione di sistemi operativi e nodi di rete. Quale migliore occasione per rispolverare un pò di sano e vecchio shell scripting?!? Nell’ambito di questo progetto abbiamo avuto bisogno di creare uno script BASH che venisse regolarmente lanciato da cron (il servizio di gestione periodica dei processi). Il nostro script, a sua volta, lancia un processo, se non è già stato lanciato precedentemente.
Ecco, il problema che ci siamo trovati a dover risolvere è proprio il seguente: come faccio a creare uno script che rileva se il processo che esso stesso lancia è già stato avviato ?
Una possibile soluzione che ho sviluppato è la seguente (sistema operativo – Ubuntu Linux):
#!/bin/bash
if [ -e /tmp/mioprocesso.pid ]; then
echo “processo in esecuzione”
exit 0
else
mioprocesso.sh &
pid=$(pidof mioprocesso.sh)
echo $pid > /tmp/mioprocesso.pid
fi
Questo script, poi, deve essere indicato in crontab affinché venga lanciato periodicamente secondo le esigenze. Ovviamente funziona, ma questo metodo non è affidabile e ce ne sono di più sofisticati e/o precisi (in questo caso sviluppato “al volo”, lo script si basa sul’esistenza o meno del file mioprocesso.pid, basta eliminarlo o rinominarlo e lo script penserà che il processo non sia partito), magari usando il comando ps in combinazione con grep o awk protremmo ottenere qualcosa di più solido…
Nella versione un pò più sofisticata lo script diventa come segue (sistema operativo – Ubuntu Linux):
#!/bin/bash
running_pid=$(ps axsf | awk ‘/mioprocesso.sh/ && !/awk/{print $2}’)
if [ $running_pid > 0 ]; then
echo “processo in esecuzione”
echo “il pid associato: $running_pid”
exit 0
else
nohup mioprocesso.sh &
fi
L’utilizzo del nohup dipende dal tipo di processo che andiamo a lanciare. Altri suggerimenti ? Problemi con i processi in background ? Usiamo fork ?Feedback, purchè costruttivi, son tutti ben accetti !
Subscribe




Ciao Emilio,
ho realizzato proprio pochi giorni fa uno script simile a quello da te proposto, atto a controllare il carico del sistema in relazione all’utilizzo di risorse di Apache. In pratica faccio esattamente ciò che hai spiegato tu, ovvero controllo mediante ps l’esistenza del(dei) processo(i), quindi controllo il carico del sistema con uptime e scelgo se riavviare Apache o avviarlo quando il processo non sia presente.
Ti riporto lo script (denudato di commenti ed echo) per completezza
[script per debian (lenny), quindi il processo di apache è apache2 e non httpd]
if ps ax | grep -v grep | grep apache2
then
temp=`uptime | awk -F’load average:’ ‘{ print $2 }’`
temp=`echo $temp | awk -F’,’ ‘{ print $1 }’`
temp=`echo $temp | awk -F’.’ ‘{ print $1 }’`
if [ $temp -gt 15 ]
then
/usr/sbin/apache2ctl restart >> /dev/null;
fi;
else
/usr/sbin/apache2ctl restart >> /dev/null
fi;
Personalmente penso che dovrò rifinire il tutto, aggiungendo anche un controllo supplementare che riesca a capire quando i processi di apache sono inattivi, in ogni caso credo che quella che hai proposto sia la soluzione migliore…
ps ax | grep -v grep suppongo serva ad eliminare il fastidioso effetto di listare anche il comando grep stesso nella lista dei risultati, vero ? @Andrea Olivato
@Emilio Tonelli
Si esatto, dato che impongo in if l’esistenza di un response dal comando ps ax | grep apache2 , se non escludessi il grep avrei sempre true…
Ciao siamo degli studenti di Emilio,
Cosa fare se un processo genera più process ID ?
Noi lo abbiamo risolto in questa maniera. Facendo un redirect del comando ps axjf all’ interno di un’altro file e con il comando wc -l si contano il numero PID all’interno del file.
Questo è il nostro codice.
#!/bin/bash
running_pid=` wc -l /home/scenario/vnuml.pid | awk ‘{print $1}’`
if [ $running_pid -gt 0 ]
then
echo “processo in esecuzione”
exit 0
else
echo “lancio”
/usr/bin/vnumlparser.pl -t /home/scenario/vnuml.xml -v -u root &
ps axsf | awk ‘/\/usr\/share\/vnuml\/kernels\/linux/ && !/awk/{print $2}’ > home/scenario/vnuml.pid
fi
@Marco Marciante e Mattia Furlan
Usare perl è barare però
Sinceramente non ho capito cosa volete ottenere… è un semplice count oppure tutti i PID?
Per il count potete usare la fantastica option -c di grep
ps aux | grep $PROCESS | grep -v grep -c
immagino che il perl fosse il programma da lanciare! Pardòn…