Beenden eines Bash-Shell-Skripts, das im Hintergrund ausgeführt wird

16

Ich verwende oft bashShell-Skripte, um einfache Befehle für viele verschiedene Dateien auszuführen. Angenommen, dass ich den folgenden habe bashShell - Skript, genannt script.sh, die das Programm / Befehl läuft fooauf drei Textdateien "a.txt", "b.txt", "c.txt":

#!/bin/bash

for strname in "a" "b" "c"
do
foo $strname".txt"
done

Angenommen, dies foo $strname".txt"ist langsam, sodass die Ausführung des Skripts viel Zeit in Anspruch nimmt (z. B. Stunden oder Tage). Aus diesem Grund möchte ich verwenden nohup, dass die Ausführung auch dann fortgesetzt wird, wenn das Terminal geschlossen oder nicht verbunden ist. Ich möchte auch, dass das Skript sofort in den Hintergrund tritt, also verwende ich den &Operator. Daher werde ich den folgenden Befehl zum Aufrufen verwenden script.sh:

nohup bash script.sh &

Dies funktioniert einwandfrei, wenn das Skript im Hintergrund und ohne Auflegen ausgeführt wird. Angenommen, ich möchte die Ausführung aus irgendeinem Grund irgendwann abbrechen. Wie kann ich das machen?

Das Problem, auf das ich gestoßen bin, ist, dass ich beim Betrachten topnur das fooEntsprechende sehe "a.txt". Ich kann diesen fooAnruf beenden , aber dann wird das fooentsprechende "b.txt"angerufen, und dann muss ich das auch beenden, und so weiter. Für Dutzende oder Hunderte von Textdateien, die in der forSchleife angegeben sind, wird es zum Schmerz, jede nach der anderen zu beenden foo! Irgendwie muss ich stattdessen das Shell-Skript selbst beenden , nicht die speziellen Aufrufe, die vom Shell-Skript ausgegeben werden.

Wenn ich den Befehl eingebe

ps -u myusername

Wo myusernameist mein Benutzername? Ich erhalte eine Liste der Prozesse, die ich ausführe. Ich sehe aber zwei unterschiedliche Prozess-IDs aufgerufen bash. Woher weiß ich, welcher dieser Prozesse meinem ursprünglichen Aufruf entspricht nohup bash script.sh &?

Andrew
quelle
@Andrew, Zeigen beide im Befehl genannten Prozesse keine Ergebnisse an? .... alternativ kannst du ps -aWu Andrew ausprobieren und mit nohup prüfen, ob du einen einzigen langen Eintrag gefunden hast .... hilft das?
Nitin
2
Abgesehen davon ist Ihr Zitat verrückt. for s in a b c; do foo "$s".txt; done
Tripleee
1
@NSD: Nein, nohupbis Sie eine Prozessauflistung aufrufen, um den von Ihnen gestarteten Job anzuzeigen, ist das lange vorbei. Sie können sich die Spalte "Nizza" in der psAusgabe ansehen, aber die Antworten hier sind nützlicher.
Tripleee

Antworten:

9

Standardmäßig pswerden die Parameter, mit denen das Programm aufgerufen wurde , nicht angezeigt . Die Optionen -fund -lbeide zeigen den vollständigen Anruf an.

ps -fu username

führt zu einer Ausgabe, die wie folgt aussieht:

username 23464 66.7  0.0  11400   628 pts/5    R    15:28   1:40 bash script.sh
j883376
quelle
2
Das ist einigermaßen nützlich, disambiguiert jedoch nicht mehrere Prozesse mit denselben Argumenten.
Tripleee
11

Sie haben mehrere Möglichkeiten. Da Ihr Prozess im Hintergrund ausgeführt wird, können Sie ihn folgendermaßen jobssuchen:

nohup bash script.sh &
...
jobs
[1]+ Running    nohup bash script.sh &
kill %1
jobs
[1]+ Terminated nohup bash script.sh &

Sie können auch pkilldie Prozesstabelle nach einer Befehlszeilenübereinstimmung durchsuchen. nämlich:

pkill -f script.sh
JRFerguson
quelle
1

Die psAusgabe (mit z. B. ps aux) enthält die Prozess-ID des übergeordneten Elements. Töte den Elternteil bashund seine Kinder werden ebenfalls getötet.

Versuchen Sie es pstree -pmit einigen Hintergrundprozessen , um eine ASCII-Visualisierung des Prozessbaums zu erhalten .

Tripleee
quelle