为什么这个无限循环没有耗尽我的系统资源?

为什么这个无限循环没有耗尽我的系统资源?

我在 BASH 中执行了以下操作:

while true;do bash;done

我写了这一行,但一开始我不确定它是否:

  • 保留在主 shell 中,并在内存或其他东西耗尽时创建尽可能多的子 shell。
  • 主 shell 生成一个子 shell,然后该子 shell 生成一个子 shell,直到该谱系耗尽内存或其他内容。

但是,我想这是第二种情况,因为一旦我运行了一个班轮,我在提示回来后不久就开始输入 exit 和另一个 exit 和 exit,exit,exit...但我仍然没有回到主壳。

现在,由于已经打开了这么多子shell,并且每个子shell都是一个程序,所以我认为每个子shell都应该有自己的PID。

所以我做了:

ps aux | grep bash

期望看到很多名称中带有 bash 的进程。

然而,没有这样的,只有两个 bash shell。

怎么可能,我想我对进程、shell、子shell和PID有一个非常错误的想法,但不知道在哪里。

答案1

您的循环在每次迭代中启动一个交互式 shell 会话。

交互式会话会给您一个提示(因为它是交互式的)。退出它会将控制权返回给循环,从而启动另一个交互式 shell。

这就是为什么您不会立即获得大量进程bash,而只有两个进程,即运行循环的父进程和为您提供新提示的子进程。


循环也可以写成

while true; do bash; done

true实用程序不接受参数,它仅返回一个零退出值,该值被 shell 解释为“true”。


如果您想要bash进程爆炸(所谓的“分叉炸弹”),您可能已经写过

while true; do { bash & }; done

bash这将在循环的每次迭代中启动一个交互式会话,但作为后台进程。由于会话是作为后台进程启动的,因此循环不会等待最新bash进程完成后再启动下一个进程。

您可能需要重新启动系统才能恢复。

这个叉子炸弹比它可能的更温和,因为它才刚刚开始每次迭代中的新流程。其他人很可能以指数方式启动流程。

答案2

您的循环正在启动无数个 shell,但一个接一个,而不是并行的。循环第一次运行时,会运行bash,这会启动一个新的 shell 并显示提示符。父 shell 等待该 shell 退出;当您键入exit、退出子 shell 并返回到父 shell 时会发生这种情况,父 shell 再次循环并运行bash,这将启动一个新 shell 并显示提示...

您可以通过运行来显示您的 shell 级别

echo $SHLVL

当您连续键入命令时,您会发现该数字不会改变exit

相关内容