Linux: Hintergrundaufgabe beenden

194

Wie töte ich die zuletzt erzeugte Hintergrundaufgabe unter Linux?

Beispiel:

doSomething
doAnotherThing
doB &
doC
doD
#kill doB
????
Flybywire
quelle
18
Wie kann dies nicht programmierungsbezogen sein? Bash-Programmierung ist keine Programmierung?
Flybywire
6
Dies ist im Überlappungsbereich zwischen SO und SU, aber ich denke, es passt hier auf SO besser. Mein Kriterium für dieses Denken ist, dass wenn @flybywire dies in einem Skript tut, es programmiert. Wenn er es nur über die Kommandozeile tun wollte, würde ich sagen, dass es zu SU gehört.
Bill the Lizard
10
Shell-Scripting wird ebenfalls programmiert.
Cletus

Antworten:

234

Dafür gibt es in bash eine spezielle Variable:

kill $!

$! wird auf die PID des zuletzt im Hintergrund ausgeführten Prozesses erweitert.

falstro
quelle
68
@ polm23; Nein, ^Zkeine Hintergrundjobs, es stoppt sie. Ein nachfolgender bgVorgang führt den eigentlichen Hintergrund aus (setzt die Ausführung im Hintergrund fort) und $!funktioniert danach wie erwartet.
Falstro
Angenommen, der Stand ????steht für einen oder mehrere Befehle, die nach dem Kill ausgeführt werden sollen. Wenn einer dieser Befehle auf der Arbeit des Hintergrundprozesses beruht, sollten Sie alle Bereinigungs- oder Abschlussaufgaben berücksichtigen, die der Hintergrundprozess möglicherweise in einem Signalhandler nachher ausführt Empfangen eines (einfangbaren) Signals. Fügen Sie am besten ein wait(gefolgt von einem syncoder sogar einem sleep <n>) direkt vor dem ersten solchen "abhängigen" Befehl hinzu.
Bestätigen Sie den
2
Zum Abschluss: Da sich ein einzelnes% auch auf den aktuellen Job bezieht, können Sie den gestoppten Job (^ z) mit "kill%" beenden. Ich benutze das fast immer nach ^ z.
bis
Dies funktioniert nur, wenn Sie die Jobsteuerung aktiviert haben, die standardmäßig nur in interaktiven Shells aktiviert ist (obwohl Sie sich auf die Verwendung von Strg-Z beziehen, beziehen Sie sich vermutlich auch auf die Verwendung einer interaktiven Shell) - aber das war schon so in anderen Antworten hier skizziert, nicht sicher, warum dies "der Vollständigkeit
halber
289

Sie können nach Jobnummer töten. Wenn Sie eine Aufgabe in den Hintergrund stellen, sehen Sie Folgendes:

$ ./script &
[1] 35341

Das [1]ist die Jobnummer und kann wie folgt referenziert werden:

$ kill %1
$ kill %%  # Most recent background job

Verwenden Sie den jobsBefehl, um eine Liste der Auftragsnummern anzuzeigen . Mehr von man bash:

Es gibt verschiedene Möglichkeiten, auf einen Job in der Shell zu verweisen. Der Charakter %führt einen Jobnamen ein. Die Auftragsnummer nkann als bezeichnet werden %n. Ein Job kann auch mit einem Präfix des Namens bezeichnet werden, mit dem er gestartet wurde, oder mit einem Teilstring, der in der Befehlszeile angezeigt wird. %ceBezieht sich beispielsweise auf einen gestoppten ceJob. Wenn ein Präfix mit mehr als einem Job übereinstimmt, meldet bash einen Fehler. Verwenden %?cebezieht sich dagegen auf jeden Job, der die Zeichenfolge cein der Befehlszeile enthält. Wenn der Teilstring mit mehr als einem Job übereinstimmt, meldet bash einen Fehler. Die Symbole %%und%+Verweisen Sie auf die Vorstellung der Shell vom aktuellen Job. Dies ist der letzte Job, der gestoppt wurde, während er im Vordergrund stand oder im Hintergrund gestartet wurde. Auf den vorherigen Job kann mit verwiesen werden %-. Bei der Ausgabe von Jobs (z. B. der Ausgabe des Jobs-Befehls) wird der aktuelle Job immer mit einem +und der vorherige Job mit einem gekennzeichnet -. Eine einzelne %(ohne zugehörige Jobspezifikation) bezieht sich auch auf den aktuellen Job.

John Kugelman
quelle
Ich denke, dies funktioniert nur, wenn die Jobsteuerung aktiviert ist. Obwohl ich denke, dass Sie es in scripts ( set -m) aktivieren können , ist es für die interaktive Verwendung vorgesehen. Siehe stackoverflow.com/questions/690266/... auch
falstro
9
Sehr nützliche Symbole, diese %1und %%- besonders. Einige Dinge sterben nicht bei Strg-C, daher müssen Sie sie bei Strg-Z drücken und dann kill -9 %%. Ein Beispiel, bei dem ich es nützlich fand, ist: while true; do mplayer <some unstable online radio>; date >> restarts.log; done- Strg-C bringt Sie nur zur nächsten Schleifeniteration. Bevor ich es tun musste psoder vielleicht jobs -l, und dann die PID erneut eingeben musste, was mühsam ist.
Tomasz Gandor
Gibt es einen für alle Jobs?
CMCDragonkai
3
@TomaszGandor Deshalb sollten Sie vielleicht ersetzen möchten while truemit while sleep 1. Dies gibt Ihnen eine kurze Verzögerung vor dem Neustart, wenn Sie damit leben können. Wenn Sie zweimal Strg-C drücken, unterbricht der zweite den Schlaf, beendet ihn mit einem Ausgang ungleich Null und bricht aus der Schleife aus.
Falstro
45

Mit dem folgenden Befehl erhalten Sie eine Liste aller Hintergrundprozesse in Ihrer Sitzung sowie die PID. Sie können es dann verwenden, um den Prozess abzubrechen.

jobs -l

Anwendungsbeispiel:

$ sleep 300 &
$ jobs -l
[1]+ 31139 Running                 sleep 300 &
$ kill 31139
Dave Vogt
quelle
25

Dies sollte alle Hintergrundprozesse beenden:

jobs -p | xargs kill -9
Prabhu sind
quelle
1
Dies ist, was ich vorher verwenden würde, aber kill -9 %%weniger
tippen
4
@TomaszGandor Damit wird nur der aktuelle Job beendet, dh der letzte Job wurde im Vordergrund gestoppt oder im Hintergrund gestartet. Der Befehl in der Antwort beendet ALLE Jobs.
Bitek
4
töte nicht -9
lesmana
2
skill doB

skill ist eine Version des Befehls kill, mit der Sie einen oder mehrere Prozesse anhand eines bestimmten Kriteriums auswählen können.

gte525u
quelle
0

Du brauchst seine PID ... benutze "ps -A", um sie zu finden.

jldupont
quelle
0

Dies ist eine nicht zum Thema gehörende Antwort, aber für diejenigen, die interessiert sind, ist sie möglicherweise wertvoll.

Wie in der Antwort von @John Kugelman bezieht sich% auf die Jobspezifikation. Wie kann man das effizient finden? Verwenden Sie den Befehl & pattern von less , anscheinend verwendet man weniger Pager (nicht so sicher). Geben Sie in man bash den Typ &% ein, und geben Sie mit Enter nur Zeilen ein, die '%' enthalten. dann Enter.

qeatzy
quelle
-3

Verwenden Sie einfach den Befehl killall:

Killall Taskname

Für weitere Informationen und erweiterte Optionen geben Sie "man killall" ein.

zakk
quelle
4
Ich denke, Killall ist ein bisschen aggressiv, wenn Sie tatsächlich einen einfachen Zugang zur PID haben. Und gefährlich auch, besonders wenn Sie root sind
Dave Vogt
3
Nicht sehr hilfreich, wenn Sie mussten killall pythonoder killall javawenn etwas Nützliches irgendwo im System ausgeführt wird.
Tomasz Gandor