警告:ほとんどのシェルでこのコマンドを実行すると、システムが破損し、回復に強制シャットダウンが必要です。
私は再帰関数:(){ :|: & };:
とその機能を理解しています。しかし、フォークシステムコールがどこにあるのかわかりません。確かではありませんが、パイプの中にあるようです|
。
答え1
のパイプによって、x | y
パイプをフォアグラウンドプロセスグループの一部として含むサブシェルが作成されます。これにより、サブシェル(パス)が引き続き生成され、fork()
フォーク爆弾が生成されます。
$ for (( i=0; i<3; i++ )); do
> echo "$BASHPID"
> done
16907
16907
16907
$ for (( i=0; i<3; i++ )); do
> echo "$BASHPID" | cat
> done
17195
17197
17199
:
ただし、ブランチはコードの最後の呼び出しであるコードが実行されるまで実際には発生しません。
フォーク爆弾の解体の仕組み:
:()
- という新しい関数を定義します。:
{ :|: & }
- 呼び出し関数をバックグラウンド呼び出し関数の別のインスタンスに再帰的に転送する関数の定義:
- フォーク爆弾機能を呼び出す
これは多くのメモリを占有しない傾向があるが、PIDを占有し、CPUサイクルを消費する。
答え2
コードの最後のビット;:
は関数を実行することです:(){ ... }
。ここでフォークが発生します。
セミコロンは最初のコマンドを終了し、関数を呼び出す別のコマンドを開始します:
。関数定義には:
独自の呼び出し()が含まれ、その呼び出しの出力はバックグラウンドバージョンにパイプされます:
。これはプロセスを無期限にサポートします。
この関数を呼び出すたびに:()
C関数を呼び出すことですfork()
。結局、これはシステムのすべてのプロセスID(PID)を使い果たします。
はい
|:&
何が起こっているのかを理解できるように、他のものに置き換えることができます。
オブザーバーの設定
ターミナルウィンドウで、次の操作を行います。
$ watch "ps -eaf|grep \"[s]leep 61\""
「ヒューズ遅延」フォーク爆弾設定
別のウィンドウでは、少し変更されたFork Bombバージョンを実行します。このバージョンは独自の制限を試して、そのバージョンが何をしているのかを調べることができます。私たちのバージョンは、この関数を呼び出す前に61秒間スリープモードに入ります:()
。
また、最初の呼び出しが行われた後にバックグラウンドに配置することもできます。Ctrl+zを入力してbg
。
$ :(){ sleep 61; : | : & };:
# control + z
[1]+ Stopped sleep 61
[2] 5845
$ bg
[1]+ sleep 61 &
最初のウィンドウでコマンドを実行すると、次のようにjobs
なります。
$ jobs
[1]- Running sleep 61 &
[2]+ Running : | : &
数分後:
$ jobs
[1]- Done sleep 61
[2]+ Done : | :
観察者に確認
一方、他のウィンドウでは以下を実行しています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
プロセス層
a は、ps -auxf
次のプロセス階層を示しています。
$ 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
...
...
清掃時間
Aはkillall bash
仕事が制御不可能になる前に仕事が起こるのを防ぎます。この方法で掃除するのは少し厳しいかもしれませんが、すべてのbash
皮を剥がさない可能性があるより柔らかく穏やかな方法は、次のことです。
フォーク爆弾が実行される疑似端末を決定します。
$ tty /dev/pts/4
擬似端末の終了
$ pkill -t pts/4
どうしたの?
との各呼び出しは、bash
コマンドを実行するシェルから呼び出されるsleep
C関数です。fork()
bash