Bash-Methode, um zu überprüfen, ob ein Prozess bereits im Hintergrund ausgeführt wird (und darauf basierend die erneute Ausführung zu überspringen)?


11

Kann ich eine Bash-Befehlszeile erstellen, die nur einen bestimmten Befehl ausführt, wenn der Prozess noch nicht ausgeführt wird (im Hintergrund)?

Wie überprüfe ich *, ob bereits ein Befehl ausgeführt wird?

(so kann ich den nächsten Befehl mit &&dazwischen hinzufügen , so dass der nächste nur ausgeführt wird, wenn der erste wahr ist).

*: testen, bestimmen, entdecken, herausfinden


3
ps -ef | grep -v grep | grep "process_name" || run_command_here
Rahul Patil

1
@ RahulPatil können Sie nur pgrep "process_name"anstelle vonps | grep | grep
Rush

hmm, ich vergesse das ..: D
Rahul Patil

1
Warum verwenden Sie keine "Sperr" -Datei, und wenn Sie das zweite Mal starten, wird sie nur gestartet, wenn die Sperrdatei verschwindet.
BitsOfNix

Der beste Weg, um zu überprüfen, ob ein Prozess existiert: stackoverflow.com/questions/3043978/…
Trevor Boyd Smith

Antworten:



3

Ich habe diese Technik von Zeit zu Zeit angewendet:

$ pgrep <process name> || <process name>

Vor pgrepfrüher auf diese Weise durchgeführt werden:

$ ps -eaf | grep -q <[p]rocess name> || <process name>

Beispiel

Das Bit mit dem [p]macht es so, dass sich das grepnicht als Ergebnis findet.

$ ps -eaf | grep -q [s]leep || sleep 10

2

Dies kann schwierig sein, da Sie separate Instanzen desselben Prozesses haben können, die unabhängig voneinander ausgeführt werden. Zum Beispiel Server, die verschiedene Ports abhören, oder Dienste, die als verschiedene Benutzer ausgeführt werden. Um zwischen diesen Instanzen zu unterscheiden, müssen Sie jeder Instanz ein eindeutiges Tag zuweisen. Das Tag ist häufig eine Datei, kann jedoch ein lokaler Socket im abstrakten Namespace, ein TCP-Port usw. sein - jede eindeutige Kennung reicht aus. Wenn es sich bei dem Tag um eine Datei handelt, kann es sich um eine reguläre Datei handeln, die eine Prozess-ID (eine PID-Datei) oder eine Named Pipe oder einen Socket enthält, den die Datei abhört usw. Im Idealfall ist das Tag ein Kommunikationsendpunkt, über den Clients eine Verbindung herstellen können zu diesem Prozess.

Jede dieser verschiedenen Arten von Tags führt zu einer unterschiedlichen Überprüfung, ob die gesuchte Instanz aktiv ist. Versuchen Sie beispielsweise mit einem lokalen Dateisocket, eine Verbindung zu diesem herzustellen, und starten Sie den Prozess, wenn dieser Socket nicht überwacht wird. Wenn es sich bei dem Tag um eine PID-Datei handelt, überprüfen Sie, ob es einen Prozess mit dieser Prozess-ID gibt. Beachten Sie jedoch, dass dieser fragil ist. Wenn der Prozess gestorben ist, gibt es möglicherweise einen nicht verwandten Prozess, der seine ID wiederverwendet hat. Beachten Sie, dass zwei Clients, die versuchen, den Prozess in kurzer Zeit zu erreichen, möglicherweise feststellen, dass der Prozess nicht vorhanden ist, und beide versuchen, ihn zu starten. Ein angemessener Schutz vor diesen Rennbedingungen kann schwierig sein.

Es ist einfacher, Instanzen zu verwalten, wenn sie alle vom selben Supervisor-Prozess gestartet werden, und dieser Supervisor-Prozess erkennt, wenn Instanzen sterben, und reagiert entsprechend. Viele Dienstüberwachungsprogramme , die dies tun können.

Wenn das Programm nicht auf einen bekannten Kommunikationsendpunkt reagiert und nicht von einem Supervisor-Programm verwaltet wird, ist das Tag des armen Mannes eine PID-Datei: eine Datei mit der Prozess-ID. Wenn Sie den Vorgang starten, schreiben Sie die PID in eine Datei mit einem festgelegten Namen. Wenn der Prozess vorhanden sein muss, lesen Sie die PID-Datei und prüfen Sie, ob es einen Prozess mit dieser PID gibt. Wenn Sie den Prozess beenden, löschen Sie die PID-Datei. Das auffälligste Problem bei einer unbeaufsichtigten PID-Datei ist, dass wenn der Prozess stirbt, die PID von einem nicht verwandten Prozess wiederverwendet werden kann. Sie sollten mindestens den Prozessnamen oder die ausführbare Prozessdatei überprüfen, um sicherzustellen, dass Sie mit dem richtigen Prozess sprechen. Viele Unix-Varianten haben einen pgrep- Befehl:pgrep SOMENAME listet die Prozesse auf, deren Name SOMENAME als Teilzeichenfolge enthält, mit zusätzlichen Optionen, um sie auf einen bestimmten Benutzer zu beschränken, eine genaue Übereinstimmung zu verlangen, um zu ändern, welche der verschiedenen möglichen Begriffe „Prozessname“ verwendet wird usw.


1

Sie könnten diesen Ansatz verwenden:

if [[ -z $(ps -C appname -opid=) ]]; then
    appname && secondapp
fi

1

Andere Optionen:

  • pgrep -xq processname
    • Entspricht nur den ersten 15 Zeichen in GNU / Linux
    • Enthält keine Vorfahren unter OS X.
  • ps -eo comm= | sed 's|.*/||' | grep -xq processname
    • Entspricht nur den ersten 15 Zeichen in GNU / Linux
    • sed 's|.*/||' Entfernt Dirname-Teile unter OS X.

In GNU / Linux werden ps -o commBefehlsnamen auf 15 Zeichen gekürzt pgrepund ps -Cnur mit den ersten 15 Zeichen abgeglichen.

ps -C (Match Command Names) wird unter OS X nicht unterstützt.

In OS X werden ps -o commdie absoluten Pfade von Befehlen und ps -co commnur Befehlsnamen gedruckt. In GNU werden ps -o commnur Befehlsnamen gedruckt und -chaben eine andere Bedeutung.

Das Pgrep von OS X enthält keine Vorgängerprozesse (wie Bash, Terminal oder Launchd) ohne -a. GNUs pgrep enthält sie standardmäßig und wird nicht unterstützt -a.

grep -xund pgrep -ximplizieren Sie nicht -F, also verwenden Sie, -Fxwenn der Prozessname Regex-Zeichen enthalten kann.


-C ist auch in meinem Cygwin nicht verfügbar :)
n611x007

1

Es tut mir leid, aber alle diese Lösungen unterstützen contab nicht, da dieselbe Befehlszeile zweimal im Ergebnis 'ps' angezeigt wird.

Also hier ist meins:

## Test pour voir si le même script tourne déjà
## Un fichier .pid est utilisé pour stocké le numéro de process
## Si le pid est en train de tourner alors on sort.
lock_file=$0".pid"
[ -r $lock_file ] && read pid <$lock_file
if [ "$pid" -gt 1 ] && [ `ps --no-headers -p "$pid" | wc -l` -gt 0 ] ; then
    echo "WARNING : le process $pid tourne deja : $0"
    ps -edf | grep `basename $0` | grep -v grep
    echo "WARNING : Arrêt de cette instance ($$)."
    exit 7
fi
echo $$ >$lock_file

Was tut dir leid? Was ist Contab? Meinen Sie das Überprüfen innerhalb eines cronJobs?
Anthon

0

Mit Bash

#!/usr/bin/env bash

[[ $# -eq 0 ]] && { echo -e "Usage:\t\t $0 <Process_name>  <Command here>"; exit 1;  }

ifnotrun(){
        local p=$1
        if ! ps -C "$1" -opid=
        then
                cmd=($@)
                echo ${cmd[@]:1}
        else
                echo "Process \"$p\" Already Running.."
                exit 1
        fi

}

ifnotrun $*

Hinweis: - Entfernen, echowenn die Ausgabe in Ordnung ist.


0

Ich werde den Fall erklären, in dem Sie den Befehl in beckgreoud ausführen. Das "$!" Speichern Sie die PID des letzten Hintergrundprozesses. Sie können es also verwenden, um es in den Prozesstabellen zu finden, die den obigen Antworten folgen:

sleep 4 &
ps -ef | grep -w  $!  ...

Der eingebaute Befehl "jobs" - versuchen Sie Folgendes:

sleep 4&
J=`jobs`
while [ "$J" ]; do
        sleep 1
        jobs # This line flush the jobs' bufer.
        J=`jobs`
done

In Bezug auf die Option "&&"

Verwenden Sie anstelle von && den Befehl wait. Im folgenden Beispiel wird myproc2 erst ausgeführt, wenn myproc1 beendet ist:

myproc1 &
wait
myproc2

0

Erhalten Sie den Status Ihres Prozesses:

ps -lp $(pgrep <YOUR_PROCESS_NAME>) | tail -1 | awk '{print $11}'

Referenz:

D    uninterruptible sleep (usually IO)
R    running or runnable (on run queue)
S    interruptible sleep (waiting for an event to complete)
T    stopped, either by a job control signal or because it is being traced
W    paging (not valid since the 2.6.xx kernel)
X    dead (should never be seen)
Z    defunct ("zombie") process, terminated but not reaped by its parent

Zum Beispiel habe ich es verwendet, um meinen Sox-Prozess in einer tmux-Sitzung bedingt abzuspielen oder anzuhalten:

/usr/local/bin/tmux if-shell -t sox "[ $(ps -lp $(pgrep sox) | tail -1 | awk '{print $11}') == 'T' ]" \
  'send -t sox "fg" Enter' \
  'send -t sox C-z'

-1

Sie können es in einem Skript verwenden:

if [ `ps -ef | grep "script.sh" | grep -v grep | wc -l` -gt 1 ] ; then
echo "RUNNING...."
else
echo "NOT RUNNING..."
fi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.