これらのbash fork爆弾の動作が異なるのはなぜですか。


16

通常のフォーク爆弾がどのように機能するかはわかりますが、一般的なbashフォーク爆弾の最後に&が必要な理由と、これらのスクリプトの動作が異なる理由はよくわかりません。

:(){ (:) | (:) }; :

そして

:(){ : | :& }; :

前者は、ログイン画面に戻る前にCPU使用率の急上昇を引き起こします。後者は代わりにシステムをフリーズさせ、ハードリブートを強制します。何故ですか?どちらも継続的に新しいプロセスを作成しますが、なぜシステムの動作が異なるのですか?

また、両方のスクリプトは、

:(){ : | : }; :

似ていると思っていたとしても、問題はまったく発生しません。bashのマニュアルページには、パイプラインのコマンドはすでにサブシェルで実行されていると記載されているため、次のように信じられます。:すでに十分です。私は信じており、新しいサブシェルでパイプラインを実行する必要がありますが、なぜそんなに変わるのですか?

編集:htopを使用してプロセスの量を制限すると、最初のバリアントはプロセスの実際のツリーを作成し、2番目のバリアントは同じレベルのすべてのプロセスを作成し、最後のバリアントはプロセスを作成しないように見えましたまったく。これは私をさらに混乱させますが、おそらくそれが何らかの形で役立つのでしょうか?


2
あなたの最後のバリアントにはセミコロンが欠けていると思います::(){ : | :; }; :
アドニス

回答:


22

警告これを生産マシンで実行しようとしないでください。しないでください。 警告:「爆弾」を試すに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

それがの効果です&

これが、&プロセスの起動を高速化する理由です。

よりシンプルな名前

b2つのコマンドを実行するためだけに呼び出される関数を作成できます。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つの新しいプロセスを「分岐」します。無限にそれを行うと爆弾が発生します。
または、もともとウサギがそう呼ばれたのは、それがとても速く繁殖するからです。


タイミング:

  1. :(){ (:) | (:) }; time :
    終了した
    実際の0m45.627s

  2. :(){ : | :; }; time :
    終了した
    実際の0m15.283s

  3. :(){ : | :& }; time :
    real 0m00.002 s
    まだ実行中


あなたの例:

  1. :(){ (:) | (:) }; :

    2回目の終了で)区切られるの}は、のより複雑なバージョンです:(){ :|:;};:。とにかく、パイプ内の各コマンドはサブシェル内で呼び出されます。これはの効果です()

  2. :(){ : | :& }; :

    スペースを持たないように記述された高速バージョンです:(){(:)|:&};:(13文字)。

  3. :(){ : | : }; : ###は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人の新しい新規ユーザーのみが機能しますbizekillall -u bizeシステムを呼び出して、ほとんどの(すべてではない)爆弾を取り除きやすくします。どれがまだ動作するかを尋ねないでください、私は教えません。しかし、まだ:非常に低いですが、安全面では、システムに適応します
これにより、「フォークボム」がシステムを崩壊させないことが保証されます

参考文献:

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.