警告これを生産マシンで実行しようとしないでください。しないでください。
警告:「爆弾」を試すにulimit -u
は、必ず使用してください。以下をお読みください[a]。
PIDと日付(時刻)を取得する関数を定義しましょう:
bize:~$ d(){ printf '%7s %07d %s\n' "$1" "$BASHPID" "$(date +'%H:%M:%S')"; }
bomb
新規ユーザー向けのシンプルで問題のない機能(自分自身を保護する:[a]を読んでください):
bize:~$ bomb() { d START; echo "yes"; sleep 1; d END; } >&2
その関数が呼び出されて実行されると、次のように機能します。
bize:~$ bomb
START 0002786 23:07:34
yes
END 0002786 23:07:35
bize:~$
コマンドdate
が実行され、「yes」が出力され、1秒間スリープし、次に閉じるコマンドdate
が表示され、最後に、関数は新しいコマンドプロンプトの出力を終了します。派手なものは何もありません。
| パイプ
このような関数を呼び出すとき:
bize:~$ bomb | bomb
START 0003365 23:11:34
yes
START 0003366 23:11:34
yes
END 0003365 23:11:35
END 0003366 23:11:35
bize:~$
ある時点で2つのコマンドが開始され、2つは1秒後に終了し、その後プロンプトが戻ります。
それがpipeが|
2つのプロセスを並行して開始する理由です。
& バックグラウンド
終了を追加して呼び出しを変更する場合&
:
bize:~$ bomb | bomb &
[1] 3380
bize:~$
START 0003379 23:14:14
yes
START 0003380 23:14:14
yes
END 0003379 23:14:15
END 0003380 23:14:15
プロンプトがすぐに戻り(すべてのアクションがバックグラウンドに送信されます)、2つのコマンドが以前のように実行されます。[1]
プロセスのPIDの前に出力される「ジョブ番号」の値に注意してください3380
。後で、パイプが終了したことを示すために同じ番号が出力されます:
[1]+ Done bomb | bomb
それがの効果です&
。
これが、&
プロセスの起動を高速化する理由です。
よりシンプルな名前
b
2つのコマンドを実行するためだけに呼び出される関数を作成できます。3行で入力します。
bize:~$ b(){
> bomb | bomb
> }
そして実行:
bize:~$ b
START 0003563 23:21:10
yes
START 0003564 23:21:10
yes
END 0003564 23:21:11
END 0003563 23:21:11
;
定義ではnoを使用していることに注意してくださいb
(要素を区切るために改行が使用されました)。ただし、1行の定義では;
、次のようにを使用するのが通常です。
bize:~$ b(){ bomb | bomb ; }
ほとんどのスペースも必須ではありませんが、同等のものを書くことができます(ただし、あまり明確ではありません)。
bize:~$ b(){ bomb|bomb;}
また、a &
を使用して分離します}
(2つのプロセスをバックグラウンドに送信します)。
爆弾。
関数を(自分自身を呼び出すことで)テールに噛み込ませると、「fork bomb」が得られます。
bize:~$ b(){ b|b;} ### May look better as b(){ b | b ; } but does the same.
また、より多くの関数をより速く呼び出すために、パイプをバックグラウンドに送信します。
bize:~$ b(){ b|b&} ### Usually written as b(){ b|b& }
必須の後に関数の最初の呼び出しを追加し;
、名前を:
次のように変更すると:
bize:~$ :(){ :|:&};:
通常次のように書かれています :(){ :|:& }; :
または、別の名前(雪だるま)を使用して、楽しい方法で記述します。
☃(){ ☃|☃&};☃
ulimit(これを実行する前に設定する必要があります)は、多くのエラーの後、プロンプトを非常にすばやく返します(エラーリストが停止してプロンプトを取得するときにEnterキーを押します)。
これが「fork bomb」と呼ばれる理由は、シェルがサブシェルを開始する方法は、実行中のシェルをフォークしてから、実行するコマンドでフォークされたプロセスにexec()を呼び出すことです。
パイプは2つの新しいプロセスを「分岐」します。無限にそれを行うと爆弾が発生します。
または、もともとウサギがそう呼ばれたのは、それがとても速く繁殖するからです。
タイミング:
:(){ (:) | (:) }; time :
終了した
実際の0m45.627s
:(){ : | :; }; time :
終了した
実際の0m15.283s
:(){ : | :& }; time :
real 0m00.002 s
まだ実行中
あなたの例:
:(){ (:) | (:) }; :
2回目の終了で)
区切られるの}
は、のより複雑なバージョンです:(){ :|:;};:
。とにかく、パイプ内の各コマンドはサブシェル内で呼び出されます。これはの効果です()
。
:(){ : | :& }; :
スペースを持たないように記述された高速バージョンです:(){(:)|:&};:
(13文字)。
:(){ : | : }; :
###はzshでは動作しますが、bashでは動作しません。
構文エラーを(bashで)、メタ文字を閉じる前に必要とされてい}
、
このよう:
:(){ : | :; }; :
[a]
新しいクリーンユーザーを作成します(私はmineと呼びますbize
)。コンソールでこの新しいユーザーにログインしますsudo -i -u bize
。または:
$ su - bize
Password:
bize:~$
max user processes
制限を確認して変更します。
bize:~$ ulimit -a ### List all limits (I show only `-u`)
max user processes (-u) 63931
bize:~$ ulimit -u 10 ### Low
bize:~$ ulimit -a
max user processes (-u) 1000
10人のみを使用すると、1人の新しい新規ユーザーのみが機能しますbize
。killall -u bize
システムを呼び出して、ほとんどの(すべてではない)爆弾を取り除きやすくします。どれがまだ動作するかを尋ねないでください、私は教えません。しかし、まだ:非常に低いですが、安全面では、システムに適応します。
これにより、「フォークボム」がシステムを崩壊させないことが保証されます。
参考文献:
:(){ : | :; }; :