gpt4 book ai didi

linux - 执行单个命令时 Bash 'swallowing' 子 shell 子进程

转载 作者:IT王子 更新时间:2023-10-29 00:32:53 29 4
gpt4 key购买 nike

遇到了意外的 bash/sh 行为,我想知道有人可以解释其背后的基本原理,并提供以下问题的解决方案。

在交互式 bash shell session 中,我执行:

$ bash -c 'sleep 10 && echo'

在 Linux 上使用 ps 看起来像这样:

\_ -bash
\_ bash -c sleep 10 && echo
\_ 睡 10

进程树是我所期望的:

  • 我的交互式 bash shell 进程 ($)
  • 子 shell 进程 (bash -c ...)
  • sleep 子进程

但是,如果我的bash -c命令 部分是单个 命令,例如:

$ bash -c 'sleep 10'

然后中间的子 shell 被吞下,我的交互式终端 session 作为子进程“直接”执行 sleep 。进程树如下所示:

\_ -bash
\_ 睡 10

所以从进程树的角度来看,这两个产生相同的结果:

  • $ bash -c 'sleep 10'
  • $ sleep 10

这是怎么回事?

现在我的问题是:有没有办法强制使用中间 shell,而不管传递给 bash -c ... 的表达式的复杂性?

(我可以将 ; echo; 之类的内容附加到我的实际命令中并且“有效”,但我宁愿不这样做。是否有更合适的方法来强制中间过程存在? )

(编辑:ps 输出中的错字;按照评论中的建议删除了 sh 标签;又一个错字)

最佳答案

居然有评论in the bash source描述了此功能的大部分基本原理:

/* If this is a simple command, tell execute_disk_command that it
might be able to get away without forking and simply exec.
This means things like ( sleep 10 ) will only cause one fork.
If we're timing the command or inverting its return value, however,
we cannot do this optimization. */
if ((user_subshell || user_coproc) && (tcom->type == cm_simple || tcom->type == cm_subshell) &&
((tcom->flags & CMD_TIME_PIPELINE) == 0) &&
((tcom->flags & CMD_INVERT_RETURN) == 0))
{
tcom->flags |= CMD_NO_FORK;
if (tcom->type == cm_simple)
tcom->value.Simple->flags |= CMD_NO_FORK;
}

bash -c '...' 情况下,CMD_NO_FORK 标志在由 should_suppress_fork function 确定时设置在 builtins/evalstring.c 中。

让 shell 执行此操作总是对您有利。只有在以下情况下才会发生:

  • 输入来自硬编码字符串,shell 在该字符串的最后一个命令处。
  • 在命令完成后没有进一步的命令、陷阱、 Hook 等要运行。
  • 退出状态不需要反转或以其他方式修改。
  • 不需要取消任何重定向。

这可以节省内存,使进程的启动时间稍微快一些(因为它不需要 forked),并确保传送到 PID 的信号直接进入您正在运行的进程,使 sh -c 'sleep 10' 的父进程能够准确确定哪个信号杀死了 sleep,如果它实际上被信号。

但是,如果出于某种原因你想抑制它,你只需要设置一个陷阱——任何陷阱都可以:

# run the noop command (:) at exit
bash -c 'trap : EXIT; sleep 10'

关于linux - 执行单个命令时 Bash 'swallowing' 子 shell 子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44576773/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com