14

根据Wikipedia:(){ :|:& };:的说法,可以使用 zsh 命令停止forkbomb while (sleep 100 &!) do; done,这应该会产生 sleep 100 进程,直到所有 forkbomb 进程都消失。这似乎很神奇;它是如何工作的?我特别好奇到底是什么“&!” 方法。

bash 中的等效命令是什么样的?

4

4 回答 4

11

分叉炸弹起作用的原因是因为在任何时候可以运行的进程数量是有限的,而分叉炸弹就是为了填补这个限制而设计的。

因为您提供的 forkbomb 代码如果无法生成子进程就会死掉,因此父进程实际上并没有闲逛,但是子进程不断创建新的 grand*-children 的事实使进程表保持满了。

因此,睡眠解决方案旨在潜入一些仅睡眠一小段时间的进程,并且对于每个设法创建的睡眠进程,发生的分叉炸弹更少。最终,睡眠进程自己填满了进程表,叉子炸弹消失了。

一旦进程表满了 sleep 进程,while 循环就可以被杀死,并且一旦它们的睡眠时间到了,sleep 进程就会死掉。问题解决了

正如已经提到的 zsh 命令的重要部分是 run-in-background &,因此 bash 命令基本上与其他答案中给出的相同:

while (sleep 100 &) do; done

除非您想在睡眠时间内注销,否则我认为nohup/!部分并不重要,但如果我错了,我很乐意直言不讳。

于 2009-02-22T12:02:45.327 回答
8

首先叉子炸弹可以写成:

foo()
{
    foo|foo&
}
foo

这使它更清楚一点 - 每次迭代都会启动两个子进程,然后终止。所以如果分叉失败,它就不会挂起。

因此,我们要做的就是让分叉暂时失败。因此,我们创建了睡眠 100 并占用进程空间的进程,就像睡眠进程一样。

zsh&!就像&但不承认新进程(在注销时不会杀死它) - 在这个例子中它可能并不重要。(手动)它可以替换为nohup

因此bash:

while (nohup sleep 100 &) do; done

应该管用。

于 2009-02-22T10:45:14.717 回答
6

我是撰写维基百科文章那部分的人(并且在我的系统上意外启动了叉形炸弹后“发现”了这种治疗方法!)。

“&!”的原因 而不是 "&" 确实是为了防止 zsh 对新进程进行工作控制,即试图关心它何时以及是否完成。我不记得为什么在我尝试工作控制时会出现问题,但确实如此。您实际上可以尝试一下,看看“治愈”是如何工作的,以及如果您不阻止工作控制会发生什么。也许作业控制的问题与 zsh 中的一些错误有关,而这些错误在 bash 中甚至不存在,并且可能在 zsh 中也不再相关。

所以尝试使用 bash 的“&”,如果作业控制受到干扰,请尝试禁用它(“set +m”),希望这会起作用。

你说得对,维基百科文章可能不应该依赖于 zsh。

于 2009-06-28T07:34:51.840 回答
2

非常有趣的问题!

根据那篇维基百科文章,完整命令的目的是创建许多无害的作业,这些作业将禁用分叉炸弹,因为它将不再能够产生更多的孩子。

根据zsh手册

如果作业以&|' or&!' 开头,则该作业将立即被拒绝。启动后,它在作业表中没有位置,不受此处描述的作业控制功能的约束。

我不确定如何使用 bash 实现相同的效果。但是,可能会执行以下操作:

nohup sleep 100 &
于 2009-02-22T10:42:34.893 回答