2009-05-29 2 views
10
ist

Ich habe ein Skript, das alle 15 Minuten läuft, aber manchmal, wenn die Box beschäftigt ist, hängt es und der nächste Prozess wird gestartet, bevor der erste fertig ist zu erstellen ein Schneeballeffekt. Wie kann ich dem Bash-Skript ein paar Zeilen hinzufügen, um vor dem Start zu prüfen, ob etwas ausgeführt wird?Wie ein Bash-Skript einchecken, wenn etwas läuft und beenden, wenn es

+1

Dupe von 185451. – Rob

+0

Siehe [http://stackoverflow.com/questions/185451/quick-and-dirtyway-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

mögliches Duplikat der [Shell-Skript-Ausführungsüberprüfung, ob es bereits läuft oder nicht] (http://stackoverflow.com/questions/16807876/shell-script-execution-check-if-it-is-ready-running-oder- nicht) – Pureferret

Antwort

3

Anstelle von Pidfile, solange Ihr Skript einen eindeutig identifizierbaren Namen hat man so etwas tun kann:

#!/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

Ich tat dies und Ich musste es ein wenig zwicken. Zunächst enthält COMMAND den vollständigen Pfad, so dass es nicht funktioniert, wenn Sie es nicht aus demselben Verzeichnis ausführen. Ich habe den Namen trotzdem fest codiert. Zweitens, aus irgendeinem Grund ps --no-header -C $ {COMMAND} | wc -l gab immer 1 zurück, ohne dass etwas lief, und da dieses Skript läuft, während es überprüft, ist das eine andere 1, also gab es immer 2 zurück. Ich musste das -gt 1 zu -gt 2 ändern und es funktionierte. Vielen Dank. –

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

pkill -0 wird wahrscheinlich besser sein. – iny

5

Warum eine Sperrdatei nicht einrichten?

So etwas wie

yourapp.lock

Sie es einfach entfernen, wenn Sie beendet verarbeiten, und es überprüfen, bevor es zu starten.

Es könnte

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

Da die korrekte Verwaltung einer Sperrdatei, insbesondere die Behandlung von Fällen, in denen ein Prozess nicht ordnungsgemäß beendet wurde und dessen Sperrdatei nicht gelöscht werden konnte, dauert es mehr als ein paar Zeilen in bash. – chaos

+1

Wenn Sie 'flock' verwenden, sind Lock-Dateien einfach zu verwalten - aber ja,' -f' zu verwenden, um ihre Existenz zu testen, ist Evil And Wrong. –

13

Sie können pidof -x verwenden getan werden, wenn Sie die Prozessnamen kennen, oder kill -0, wenn Sie die PID kennen.

Beispiel:

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

Dies ist der beste Weg. – olle

+1

Stellen Sie sicher, dass Sie das -x-Flag verwenden, wenn Sie ein Skript überprüfen, oder Sie erhalten keine Übereinstimmung, weil es nach 'Bash' – Nathan

+1

suchen wird, wenn nur PIDOF Teil von FreeBSD war ... –

1

zu erweitern, was @bgy sagt, die sichere Atom Weise eine Sperrdatei zu erstellen, wenn es noch nicht vorhanden ist, und nicht, wenn es nicht der Fall ist, ist zu Erstellen Sie eine temporäre Datei und verbinden Sie sie dann mit der Standardsperrdatei. Dies schützt vor einem anderen Prozess, der die Datei zwischendurch erstellt, während Sie sie testen und Sie erstellen. Hier

ist die Lock-Datei Code aus meinem Stunden Backup-Skript:

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

Vergessen Sie nicht, sowohl die Sperrdatei und die temporäre Datei zu löschen, wenn Sie fertig sind, auch wenn Sie früh durch einen Ausgang Error.

1

Verwenden Sie dieses Skript:

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

...script here... 

Dieses Skript wird eine Datei erstellen und diese an der Ausfahrt entfernen.

2

hatte ich vor kurzem die gleiche Frage und fand von oben, dass töten -0 am besten für meine Fall:

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

Dies ist, wie ich es tun in einer meiner Cronjobs

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 

und die Lock-Datei am Ende des Skripts löschen

echo "Removing lock $lockfile ..." 
rm $lockfile 
Verwandte Themen