叉形炸彈是如何工作的?
- 警告不要嘗試在生產機器上執行它
在閱讀有關該主題的維基百科頁面時,我通常遵循以下程式碼的情況:
:(){ :|:& };:
描述摘錄
以下叉形炸彈在 2002 年作為藝術品出現;56 它的確切來源未知,但它在 2002 年之前存在於 Usenet。通過將以下 13 個字元粘貼到 UNIX shell(如bash或zsh )來執行炸彈。它通過定義一個名為 ‘:’ 的函式進行操作,該函式呼叫自身兩次,一次在前台,一次在後台。
然而,最後一點對我來說並不完全清楚。我看到函式定義:
:(){ ... }
但還有什麼事情發生?其他外殼(例如
ksh
,csh
, )tcsh
是否也遭受同樣的命運,能夠構造類似的東西?
這個叉子炸彈總是讓我想起一位 AI 程式老師在我參加的第一堂課中所說的話“要理解遞歸,首先你必須理解遞歸”。
在它的核心,這個炸彈是一個遞歸函式。本質上,您創建了一個函式,它呼叫自己,呼叫自己,呼叫自己……直到消耗系統資源。在這個特定的例子中,遞歸通過使用管道將函式傳遞給自身並作為背景來放大。
我已經在StackOverflow上看到了這個答案,我認為那裡給出的例子最能說明這一點,因為它更容易一目了然地看到它的作用(從上面的連結中竊取……)
☃(){ ☃|☃& };☃
定義 bug 函式
☃() { ... }
,其主體呼叫自身(bug 函式),將輸出通過管道傳輸到自身(bug 函式)☃|☃
,並將結果作為背景&
。然後,函式定義好後,實際呼叫bug函式,; ☃
.我注意到,至少在我的 Arch VM 上,對程序進行後台處理並不是要求具有相同的最終結果、消耗所有可用程序空間並渲染主機 b0rked。實際上,現在我已經說過,它似乎有時會終止逃跑程序,並且在經過一屏後
-bash: fork: Resource temporarily unavailable
它會以 a 停止Terminated
(並journalctl
顯示 bash 核心轉儲)。要回答您關於 csh/tcsh 的問題,這些 shell 都不支持功能,您只能使用別名。因此,對於那些 shell,您必須編寫一個遞歸呼叫自身的 shell 腳本。
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()
似乎有預期的結果。