Ich habe ein Shell-Skript geschrieben, um ein Verzeichnis mit dem Dienstprogramm inotifywait von inotifyt-tools zu überwachen. Ich möchte, dass dieses Skript kontinuierlich im Hintergrund ausgeführt wird, aber ich möchte es auch stoppen können, wenn dies gewünscht wird.
Um es kontinuierlich laufen zu lassen, habe ich verwendet while true
; so was:
while true;
do #a set of commands that use the inotifywait utility
end
Ich habe es in einer Datei gespeichert /bin
und ausführbar gemacht. Um es im Hintergrund laufen zu lassen, habe ich nohup <script-name> &
das Terminal benutzt und geschlossen.
Ich weiß nicht, wie ich dieses Skript stoppen soll. Ich habe bei den Antworten sah hier und eine sehr eng verwandte Frage hier .
UPDATE 1: Auf der Grundlage der Antwort von @InfectedRoot unten konnte ich mein Problem mit der folgenden Strategie lösen. Erste Benutzung
ps -aux | grep script_name
und verwenden sudo kill -9 <pid>
, um die Prozesse zu beenden. Ich musste dann pgrep inotifywait
und sudo kill -9 <pid>
wieder für die zurückgegebene ID verwenden.
Das funktioniert, aber ich denke, das ist ein chaotischer Ansatz. Ich suche nach einer besseren Antwort.
UPDATE 2: Die Antwort besteht darin , 2 Prozesse zu beenden . Dies ist wichtig, da das Ausführen des Skripts in der Befehlszeile zwei Prozesse initiiert, einen das Skript selbst und zwei den inotify-Prozess .
-9
Option auskill
und mit nurkill
nehmen das Chaos aus ihm heraus.-9
Option hier total wärekill
. : Pkill
es gibt Ihnen die pgid mit einem Minus Präfix:kill -- -<pgid>
,kill -9 -<pgid>
usw.Antworten:
So verbessern, verwenden
killall
und kombinieren Sie die Befehle:Oder machen Sie alles in einer Zeile:
quelle
Error: no process
sollte nur bedeuten, dass du es bereits getötet hast. Sie können es testen, indem Sie zwei andere Programme wie VLC & Geany öffnen und es stattdessen mit ihnen versuchen.grep -v grep
indemgrep script_name
ingrep -e "[s]cript_name"
.Listen Sie die Hintergrundjobs mit auf
# jobs
Wählen Sie dann die vorherige Auftragsnummer und führen Sie sie aus
Beispiel
wird in den Vordergrund bringen.
Beenden Sie es dann mit STRG + C oder auf einfachere Weise, um die PID des Skripts mithilfe von zu ermitteln
Dann töte mit pid
quelle
jobs
Befehl die laufenden Jobs nur in der Shell anzeigte. Sobald ich ein bestimmtes Terminalfenster geschlossen hatte, war der einzige Weg, auf sie zuzugreifen, überps
(siehe oben). Es ist also sicher, dass Sie sich das nicht ausdenken.Sie können mit
ps
+grep
oderpgrep
erhalten der Prozess Name / pid ; später benutzekillall
/pkill
um den Prozessnamen zu töten oder benutzekill
um pid zu töten. Alle folgenden Schritte sollten funktionieren.Das Wichtigste ist, dass Sie sicherstellen, dass Sie nur die genauen Prozesse beenden , die Sie töten möchten.
pkill
/pgrep
entspricht eher einem Muster als dem genauen Namen , ist also gefährlicher; Hier-x
wird hinzugefügt, um dem genauen Namen zu entsprechen.Auch bei der Verwendung von
pgrep
/pkill
benötigen Sie möglicherweise-f
um der vollständigen Befehlszeile zu entsprechen (wieps aux
auch)-a
um auch den Prozessnamen zu drucken.quelle
pgrep
/pkill
. Wenn das immer noch schief geht, können Sie espgrep
ohne -x versuchen . Grundsätzlich halte ich es nicht für gut, den Prozess innerhalb eines Zeilenbefehls abzubrechen, ohne zu überprüfen, ob andere Prozesse übereinstimmen.Wie Sie wahrscheinlich sehen können, gibt es viele Möglichkeiten, dies zu tun.
In Bezug auf Ihr "UPDATE # 2" - im Allgemeinen werden durch das Beenden eines Prozesses in einer Eltern-Kind-Hierarchie im Allgemeinen alle zugehörigen Prozesse beendet. Es gibt jedoch viele Ausnahmen. Idealerweise möchten Sie das letzte "Kind" in einem Prozessbaum beenden. Die Eltern dieses Kindes sollten dann beendet werden, wenn keine anderen Aufgaben ausgeführt werden müssen. Wenn Sie jedoch einen Elternteil töten, sollte das Signal an Kinder weitergeleitet werden, wenn der Elternteil stirbt, und die Kinder sollten ebenfalls beendet werden. Es gibt jedoch Fälle, in denen die untergeordneten Prozesse das Signal möglicherweise ignorieren (über Fallen oder ähnliche Mechanismen) und fortgesetzt werden Ein Wille auszuführen wird vom 'init'-Prozess (oder ähnlichem) geerbt. Aber dieses Thema des Prozessverhaltens kann komplex werden und ich lasse es einfach dort ...
Eine Methode, die mir gefällt, wenn ich kein Steuerungsskript verwenden möchte (siehe Beschreibung), ist die Verwendung des Dienstprogramms 'screen', um den Prozess zu starten und zu verwalten. Der Befehl 'screen' ist voll von Funktionen und kann einige Zeit in Anspruch nehmen, um ihn zu beherrschen. Ich möchte Sie dazu ermutigen, die Manpage "Bildschirm" zu lesen, um eine vollständige Erklärung zu erhalten. Ein schnelles Beispiel, um einen Prozess im Hintergrund zu starten, wäre der Befehl:
Bildschirm -d -m / Pfad / zu / Programm
Dies startet "/ path / to / program" innerhalb einer "Bildschirm" -Sitzung.
Sie können Ihre laufende Sitzung mit dem folgenden Befehl anzeigen:
Bildschirm -ls
Und Sie können sich jederzeit mit dem folgenden Befehl wieder mit Ihrem laufenden Programm verbinden:
Bildschirm -r
Und dann beenden Sie es einfach mit einem ^ C oder was auch immer.
Neben der Schönheit, nach Belieben wieder eine Verbindung zu Ihrem Prozess herstellen zu können, besteht darin, dass der Bildschirm alle stdout () erfasst, die Ihr Programm möglicherweise erzeugt.
Meine persönliche Präferenz in diesen Angelegenheiten ist jedoch ein Kontrollprogramm, das das Starten und Stoppen eines Prozesses verwaltet. Dies kann etwas kompliziert werden und erfordert einige wohl komplizierte Skripte. Und wie bei jedem Skript gibt es Dutzende guter Möglichkeiten, dies zu tun. Ich habe ein Bash-Beispiel für eine Methode beigefügt, mit der ich Anwendungen routinemäßig starte und stoppe. Wenn Ihre Aufgabe einfach ist, können Sie sie direkt in das Steuerungsskript einfügen - oder Sie können dieses Steuerungsskript ein anderes externes Programm aufrufen lassen. Beachten Sie, dass dieses Beispiel in Bezug auf die Verwaltung des Prozesses keineswegs umfassend ist. Ich habe die Möglichkeit von Szenarien wie den folgenden ausgelassen: Stellen Sie sicher, dass das Skript nicht bereits ausgeführt wird, wenn Sie die Option "Start" verwenden, und überprüfen Sie, ob die ausgeführte PID tatsächlich der von Ihnen gestartete Prozess ist (z. B. Ihr Skript wurde nicht ausgeführt). Es ist gestorben und ein anderer Prozess wurde mit derselben PID gestartet. Dabei wurde überprüft, ob das Skript bei der ersten Anforderung zum Beenden tatsächlich geantwortet (beendet) hat. Das Durchführen all dieser Überprüfungen kann kompliziert werden, und ich wollte das Beispiel nicht zu lang und komplex machen. Möglicherweise möchten Sie das Beispiel ändern, um Ihr Shell-Scripting zu üben.
Speichern Sie den folgenden Code in einer Datei namens "programctl" und machen Sie ihn mit dem Befehl ausführbar:
chmod 755 programctl
Bearbeiten Sie dann die Datei und fügen Sie Ihren Code / Ihr Skript in den Fallabschnitt ein, der mit "myscript" beginnt.
Sobald alles vorhanden ist und das "programctl" sich im aktuellen Verzeichnis befindet, können Sie Ihr Programm starten mit:
./programctl start
Und hör auf mit:
./programctl stop
Prost.
quelle