Emilio Tonelli

"se sei inattivo mostra movimento, se sei attivo mostrati immobile" - L'arte della guerra (Sun Tzu)

BASH Scripting e cron: appunti sulla gestione di un proprio processo

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 !

VN:F [1.8.4_1055]
Rating: 0.0/5 (0 votes cast)
VN:F [1.8.4_1055]
Rating: 0 (from 0 votes)


può interessarti anche...

6 Risposte

  1. Andrea Olivato scrive:

    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…

    UN:F [1.8.4_1055]
    Rating: 0.0/1 (0 votes cast)
    UN:F [1.8.4_1055]
    Rating: 0 (from 0 votes)
  2. Emilio Tonelli scrive:

    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

    UA:F [1.8.4_1055]
    Rating: 0.0/1 (0 votes cast)
    UA:F [1.8.4_1055]
    Rating: 0 (from 0 votes)
  3. Andrea Olivato scrive:

    @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…

    UN:F [1.8.4_1055]
    Rating: 0.0/1 (0 votes cast)
    UN:F [1.8.4_1055]
    Rating: 0 (from 0 votes)
  4. Marco Marciante e Mattia Furlan scrive:

    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

    UN:F [1.8.4_1055]
    Rating: 0.0/1 (0 votes cast)
    UN:F [1.8.4_1055]
    Rating: 0 (from 0 votes)
  5. Andrea Olivato scrive:

    @Marco Marciante e Mattia Furlan

    /usr/bin/vnumlparser.pl

    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

    UN:F [1.8.4_1055]
    Rating: 0.0/1 (0 votes cast)
    UN:F [1.8.4_1055]
    Rating: 0 (from 0 votes)
  6. Andrea Olivato scrive:

    immagino che il perl fosse il programma da lanciare! Pardòn… :)

    UN:F [1.8.4_1055]
    Rating: 0.0/1 (0 votes cast)
    UN:F [1.8.4_1055]
    Rating: 0 (from 0 votes)

Commenti chiusi.