Das letzte Bit des Codes ;:
führt die Funktion aus :(){ ... }
. Hier tritt die Gabel auf.
Das Semikolon beendet den ersten Befehl und wir starten einen anderen, dh wir rufen die Funktion auf :
. Die Definition dieser Funktion beinhaltet einen Aufruf an sich selbst ( :
) und die Ausgabe dieses Aufrufs wird an eine Hintergrundversion weitergeleitet :
. Dies beschleunigt den Prozess auf unbestimmte Zeit.
Jedes Mal, wenn Sie die Funktion :()
aufrufen, rufen Sie die C-Funktion auf fork()
. Letztendlich werden dadurch alle Prozess-IDs (PIDs) im System erschöpft.
Beispiel
Sie können das |:&
mit etwas anderem austauschen, um eine Vorstellung davon zu bekommen, was los ist.
Richten Sie einen Beobachter ein
Führen Sie in einem Terminalfenster Folgendes aus:
$ watch "ps -eaf|grep \"[s]leep 61\""
Richten Sie die Gabelbombe "Sicherung verzögert" ein
In einem anderen Fenster führen wir eine leicht modifizierte Version der Gabelbombe aus. Diese Version wird versuchen, sich selbst zu drosseln, damit wir untersuchen können, was es tut. Unsere Version wartet 61 Sekunden, bevor sie die Funktion aufruft :()
.
Außerdem wird der erste Aufruf nach dem Aufrufen ebenfalls im Hintergrund ausgeführt. Ctrl+ z, dann tippe bg
.
$ :(){ sleep 61; : | : & };:
# control + z
[1]+ Stopped sleep 61
[2] 5845
$ bg
[1]+ sleep 61 &
Wenn wir nun den jobs
Befehl im Anfangsfenster ausführen, sehen wir Folgendes:
$ jobs
[1]- Running sleep 61 &
[2]+ Running : | : &
Nach ein paar Minuten:
$ jobs
[1]- Done sleep 61
[2]+ Done : | :
Checken Sie mit dem Beobachter ein
In der Zwischenzeit in dem anderen Fenster, in dem wir laufen watch
:
Every 2.0s: ps -eaf|grep "[s]leep 61" Sat Aug 31 12:48:14 2013
saml 6112 6108 0 12:47 pts/2 00:00:00 sleep 61
saml 6115 6110 0 12:47 pts/2 00:00:00 sleep 61
saml 6116 6111 0 12:47 pts/2 00:00:00 sleep 61
saml 6117 6109 0 12:47 pts/2 00:00:00 sleep 61
saml 6119 6114 0 12:47 pts/2 00:00:00 sleep 61
saml 6120 6113 0 12:47 pts/2 00:00:00 sleep 61
saml 6122 6118 0 12:47 pts/2 00:00:00 sleep 61
saml 6123 6121 0 12:47 pts/2 00:00:00 sleep 61
Prozesshierarchie
Und a ps -auxf
zeigt diese Prozesshierarchie:
$ ps -auxf
saml 6245 0.0 0.0 115184 5316 pts/2 S 12:48 0:00 bash
saml 6247 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
....
....
saml 6250 0.0 0.0 115184 5328 pts/2 S 12:48 0:00 bash
saml 6268 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
saml 6251 0.0 0.0 115184 5320 pts/2 S 12:48 0:00 bash
saml 6272 0.0 0.0 100988 468 pts/2 S 12:48 0:00 \_ sleep 61
saml 6252 0.0 0.0 115184 5324 pts/2 S 12:48 0:00 bash
saml 6269 0.0 0.0 100988 464 pts/2 S 12:48 0:00 \_ sleep 61
...
...
Putzzeit
A killall bash
stoppt die Dinge, bevor sie außer Kontrolle geraten. Wenn Sie auf diese Weise bereinigen, ist dies möglicherweise etwas umständlich. Dies ist eine schonendere Methode, die möglicherweise nicht alle bash
Muscheln abreißt.
Bestimmen Sie, in welchem Pseudoterminal die Gabelbombe laufen wird
$ tty
/dev/pts/4
Töte das Pseudoterminal
$ pkill -t pts/4
So was ist los?
Nun, jeder Aufruf von bash
und sleep
ist ein Aufruf der C-Funktion fork()
von der bash
Shell aus, von der aus der Befehl ausgeführt wurde.