2009-05-29 26 views
10

Ho uno script che viene eseguito ogni 15 minuti ma a volte se la casella è occupata, si blocca e il processo successivo inizierà prima che il primo abbia finito di creare un effetto valanga. Come posso aggiungere un paio di linee allo script di bash per verificare se qualcosa è in esecuzione prima di iniziare?Come controllare uno script bash se qualcosa è in esecuzione e uscire se è

+1

Dupe di 185451. – Rob

+0

Vedi [http://stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-running-at-a](http : //stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-runnin g-at-a). – Rob

+0

possibile duplicazione di [verifica esecuzione script shell se è già in esecuzione o meno] (http://stackoverflow.com/questions/16807876/shell-script-execution-check-if-it-is-already-running-or- non) – Pureferret

risposta

3

Al posto di pidfile, fino a quando lo script ha un nome identificabile in modo univoco che si può fare qualcosa di simile:

#!/bin/bash 
COMMAND=$0 
# exit if I am already running 
RUNNING=`ps --no-headers -C${COMMAND} | wc -l` 
if [ ${RUNNING} -gt 1 ]; then 
    echo "Previous ${COMMAND} is still running." 
    exit 1 
fi 
... rest of script ... 
+3

Ho fatto questo e Ho dovuto modificarlo un po '. Innanzitutto, COMMAND include il percorso completo, quindi, a meno che non lo si esegua dalla stessa dir, non funzioni. Ho codificato il nome comunque. Secondo, per qualche ragione ps --no-headers -C $ {COMMAND} | wc -l ha sempre restituito 1 con niente in esecuzione e dal momento che questo script è in esecuzione mentre sta verificando che è un altro 1 quindi è sempre ritornato 2. Ho dovuto cambiare il -gt 1 in -gt 2 e ha funzionato. Grazie. –

3
pgrep -f yourscript >/dev/null && exit 
+0

pkill -0 yourscript sarebbe probabilmente migliore – iny

5

Perché non impostare un file di blocco?

Qualcosa di simile

yourapp.lock

semplicemente rimuovere quando si elabora è finito, e controllare per prima per lanciarlo.

potrebbe essere fatto utilizzando

if [ -f yourapp.lock ]; then 
echo "The process is already launched, please wait..." 
fi 
+1

Poiché la corretta gestione di un file di blocco, in particolare la gestione del caso in cui un processo è stato interrotto in modo errato e non è riuscito a cancellare il suo file di blocco, richiede più di un paio di righe in bash. – chaos

+1

Se si utilizza 'flock', i file di blocco sono facili da gestire, ma sì, usando' -f' per verificare la loro esistenza è Evil And Wrong. –

13

È possibile utilizzare pidof -x se si conosce il nome del processo, o kill -0 se si conosce il PID.

Esempio:

if pidof -x vim > /dev/null 
then 
    echo "Vim already running" 
    exit 1 
fi 
+1

Questo è il modo migliore. – olle

+1

Assicurati di usare il flag -x se stai controllando uno script, o non otterrai una corrispondenza, perché cercherà 'bash' – Nathan

+1

se solo pidof faceva parte di FreeBSD ... –

1

Per espandere su ciò @bgy dice, la cassaforte atomica modo per creare un file di blocco se non esiste ancora, e non riescono se non lo fa, è quello di crea un file temporaneo, quindi collegalo direttamente al file di blocco standard. Questo protegge da un altro processo che crea il file tra il test e la creazione.

Ecco il codice di blocco del file dal mio script di backup ogni ora:

echo $$ > /tmp/lock.$$ 
if ! ln /tmp/lock.$$ /tmp/lock ; then 
     echo "previous backup in process" 
     rm /tmp/lock.$$ 
     exit 
fi 

Non dimenticare di eliminare sia il file di blocco e il file temporaneo quando hai finito, anche se si esce in anticipo attraverso un errore.

1

Usa questo script:

FILE="/tmp/my_file" 
if [ -f "$FILE" ]; then 
    echo "Still running" 
    exit 
fi 
trap EXIT "rm -f $FILE" 
touch $FILE 

...script here... 

Questo script creerà un file e rimuoverlo in uscita.

2

ho avuto di recente la stessa domanda e ha scoperto dall'alto che uccidono -0 è meglio per la mia caso:

echo "Starting process..." 
run-process > $OUTPUT & 
pid=$! 
echo "Process started pid=$pid" 
while true; do 
    kill -0 $pid 2> /dev/null || { echo "Process exit detected"; break; } 
    sleep 1 
done 
echo "Done." 
3

Questo è come lo faccio in uno dei miei posti di lavoro cron

lockfile=~/myproc.lock 
minutes=60 
if [ -f "$lockfile" ] 
then 
    filestr=`find $lockfile -mmin +$minutes -print` 
    if [ "$filestr" = "" ]; then 
    echo "Lockfile is not older than $minutes minutes! Another $0 running. Exiting ..." 
    exit 1 
    else 
    echo "Lockfile is older than $minutes minutes, ignoring it!" 
    rm $lockfile 
    fi 
fi 

echo "Creating lockfile $lockfile" 
touch $lockfile 

ed eliminare il file di blocco alla fine dello script

echo "Removing lock $lockfile ..." 
rm $lockfile 
Problemi correlati