web-dev-qa-db-ja.com

フォーク爆弾はどのように機能しますか?

  • 警告本稼働マシンでこれを実行しようとしないでください

トピックに関するウィキペディアのページ を読むとき、私は通常、次のコードで何が起こっているのかを追跡します。

:(){ :|:& };:

説明の抜粋

次のフォーク爆弾は2002年に芸術として発表されました; 56 正確な起源は不明ですが、存在しました爆弾は、次の13文字を [〜#〜] unix [〜#〜]bash または-などのシェルに貼り付けることによって実行されます。 zsh 。フォアグラウンドで1回とバックグラウンドで1回、自分自身を2回呼び出す「:」という関数を定義して動作します。

しかし、最後のビットは私には完全に明確ではありません。私は関数の定義を見ます:

:(){ ... }

しかし、他に何が起こっているのでしょうか?また、kshcshtcshなどの他のシェルも、同様のものを構築できるという同じ運命にありますか?

22
slm

このフォーク爆弾は、私が出席した最初のレッスンの1つでAIプログラミングの先生が言った「再帰を理解するには、最初に再帰を理解する必要がある」ということを常に思い出させます。

基本的に、この爆弾は 再帰的 関数です。基本的に、システムリソースが消費されるまで、自分自身を呼び出す関数、自分自身を呼び出す関数、自分自身を呼び出す関数を作成します。この特定の例では、再帰は、関数をそれ自体にパイプしてANDバックグラウンド化することによって増幅されます。

私はこれが StackOverflow で答えられるのを見ました、そしてそこに与えられた例がそれを最もよく説明すると思います、それはそれが一目でそれが何をするかを見るのが簡単だからです(上のリンクから盗まれました...)

_☃(){ ☃|☃& };☃
_

本体がそれ自体を呼び出すバグ関数☃() { ... }を定義し(バグ関数)、出力をそれ自体にパイプします(バグ関数)_☃|☃_、および結果のバックグラウンド_&_。次に、関数を定義した後、実際にバグ関数_; ☃_を呼び出します。

少なくとも私のArch VMでは、プロセスをバックグラウンド化する必要は、すべての使用可能なプロセススペースを消費してホストをレンダリングするために同じ最終結果を得る必要がないことに注意してください。実際に、私はそれが暴走プロセスを時々終了させるようで、_-bash: fork: Resource temporarily unavailable_の全画面表示の後にTerminatedで停止します(そしてjournalctlはbashコアダンプを表示します) 。

Csh/tcshに関する質問に答えるには、これらのシェルのどちらも関数をサポートしておらず、エイリアスしか作成できません。そのため、これらのシェルでは、再帰的に自分自身を呼び出すシェルスクリプトを記述する必要があります。

zshは同じ運命をたどり(同じコードで)、コアダンプせず、ArchにOut of memory: Kill process 216 (zsh) score 0 or sacrifice child.を与えますが、それでもフォークは継続します。しばらくすると、Killed process 162 (systemd-logind) ...と表示されます(引き続きフォークzshが引き続き存在します)。

Archにはpacmanバージョンのkshがないようなので、代わりにdebianで試さなければなりませんでした。 kshオブジェクトは_:_を関数名として使用しますが、何かを使用します-代わりにb()を使用すると、望ましい結果が得られるようです。

24
Drav Sloan