【发布时间】:2009-02-22 10:20:44
【问题描述】:
根据Wikipedia,forkbomb :(){ :|:& };: 可以使用 zsh 命令while (sleep 100 &!) do; done 停止,这应该会产生 sleep 100 进程,直到所有 forkbomb 进程都消失。这似乎很神奇;它是如何工作的?我特别好奇到底是什么“&!”意思。
bash 中的等效命令是什么样的?
【问题讨论】:
根据Wikipedia,forkbomb :(){ :|:& };: 可以使用 zsh 命令while (sleep 100 &!) do; done 停止,这应该会产生 sleep 100 进程,直到所有 forkbomb 进程都消失。这似乎很神奇;它是如何工作的?我特别好奇到底是什么“&!”意思。
bash 中的等效命令是什么样的?
【问题讨论】:
fork-bomb 之所以起作用,是因为在任何时候可以运行的进程数量是有限的,而 fork-bomb 旨在填补这个限制。
由于您提供的 forkbomb 代码如果无法生成子进程就会死掉,因此父进程实际上并没有闲置,但子进程不断创建新的 grand*-children 的事实使进程表保持满。
因此,睡眠解决方案旨在潜入一些只睡眠一小段时间的进程,并且对于每个设法创建的睡眠进程,发生的分叉炸弹更少。最终,睡眠进程自己填满了进程表,并且 fork 炸弹消失了。
一旦进程表已满,休眠进程就可以终止 while 循环,一旦它们的休眠时间结束,休眠进程就会终止。 问题解决了。
正如已经提到的,zsh 命令的重要部分是后台运行&,因此 bash 命令与其他答案中给出的基本相同:
while (sleep 100 &) do; done
我认为nohup/! 部分并不重要,除非您想在睡眠时间内退出,但如果我错了,我很乐意直言不讳。
【讨论】:
首先可以写分叉炸弹:
foo()
{
foo|foo&
}
foo
这让它更清楚一点 - 每次迭代都会启动两个子进程,然后终止。所以如果分叉失败,它就不会挂起。
因此,我们要做的就是让分叉暂时失败。因此,我们创建了睡眠 100 并占用进程空间的进程,就像睡眠进程一样。
zsh &! 类似于 & 但不承认新进程(在注销时不会杀死它) - 在这个例子中它可能并不重要。 (manual) 可以替换成nohup。
因此 bash:
while (nohup sleep 100 &) do; done
应该可以。
【讨论】:
我是撰写 Wikipedia 文章那部分的人(并且在我的系统上意外启动了 fork 炸弹后“发现”了这种治疗方法!)。
“&!”的原因而不是 "&" 确实是为了防止 zsh 对新进程进行工作控制,即试图关心它何时以及是否完成。我不记得为什么在我尝试工作控制时会出现问题,但确实如此。您实际上可以尝试一下,看看“治愈”是如何工作的,以及如果您不阻止工作控制会发生什么。也许作业控制的问题与 zsh 中的一些错误有关,而这些错误在 bash 中甚至不存在,也许它在 zsh 中也不再相关。
所以尝试只使用 bash 的“&”,如果作业控制受到干扰,请尝试禁用它(“set +m”),希望这会起作用。
你说得对,维基百科文章可能不应该依赖于 zsh。
【讨论】:
非常有趣的问题!
根据那篇 Wikipedia 文章,完整命令的目的是创建许多无害的作业,这些作业将禁用分叉炸弹,因为它不再能够产生更多的孩子。
根据zsh manual,
如果作业以
&|' or&!' 开始, 然后该工作立即被拒绝。 启动后没有 放在工作表中,而不是 受制于作业控制功能 在这里描述。
我不确定如何使用 bash 实现相同的效果。但是,可能会执行以下操作:
nohup sleep 100 &
【讨论】: