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
ps -ef | grep -v grep | grep "process_name" || run_command_here
pgrep "process_name"
anstelle vonps | grep | grep
Antworten:
Verwenden Sie Daemontools . Mit können Sie
svok
überprüfen, ob gerade ein Dienst- / Dämon- / Hintergrundprozess ausgeführt wird.Für andere Methoden siehe:
quelle
Ich habe diese Technik von Zeit zu Zeit angewendet:
Vor
pgrep
früher auf diese Weise durchgeführt werden:Beispiel
Das Bit mit dem
[p]
macht es so, dass sich dasgrep
nicht als Ergebnis findet.quelle
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.quelle
Sie könnten diesen Ansatz verwenden:
quelle
Andere Optionen:
pgrep -xq processname
ps -eo comm= | sed 's|.*/||' | grep -xq processname
sed 's|.*/||'
Entfernt Dirname-Teile unter OS X.In GNU / Linux werden
ps -o comm
Befehlsnamen auf 15 Zeichen gekürztpgrep
undps -C
nur mit den ersten 15 Zeichen abgeglichen.ps -C
(Match Command Names) wird unter OS X nicht unterstützt.In OS X werden
ps -o comm
die absoluten Pfade von Befehlen undps -co comm
nur Befehlsnamen gedruckt. In GNU werdenps -o comm
nur Befehlsnamen gedruckt und-c
haben 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 -x
undpgrep -x
implizieren Sie nicht-F
, also verwenden Sie,-Fx
wenn der Prozessname Regex-Zeichen enthalten kann.quelle
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:
quelle
cron
Jobs?Mit Bash
Hinweis: - Entfernen,
echo
wenn die Ausgabe in Ordnung ist.quelle
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:
Der eingebaute Befehl "jobs" - versuchen Sie Folgendes:
In Bezug auf die Option "&&"
Verwenden Sie anstelle von && den Befehl wait. Im folgenden Beispiel wird myproc2 erst ausgeführt, wenn myproc1 beendet ist:
quelle
Erhalten Sie den Status Ihres Prozesses:
ps -lp $(pgrep <YOUR_PROCESS_NAME>) | tail -1 | awk '{print $11}'
Referenz:
Zum Beispiel habe ich es verwendet, um meinen Sox-Prozess in einer tmux-Sitzung bedingt abzuspielen oder anzuhalten:
quelle
Sie können es in einem Skript verwenden:
quelle