【发布时间】:2017-11-18 11:52:30
【问题描述】:
遇到了意想不到的bash/sh 行为,我想知道有人可以解释其背后的原因,并为以下问题提供解决方案。
在交互式bash shell 会话中,我执行:
$ bash -c 'sleep 10 && echo'
在 Linux 上使用ps 看起来像这样:
\_ -bash
\_ bash -c sleep 10 && echo
\_ sleep 10
进程树是我所期望的:
- 我的交互式 bash shell 进程 (
$) - 一个子 shell 进程 (
bash -c ...) - 睡眠子进程
但是,如果我的bash -c 的 command 部分是 single 命令,例如:
$ bash -c 'sleep 10'
然后中间的子外壳被吞下,我的交互式终端会话作为子进程“直接”执行睡眠。 进程树如下所示:
\_ -bash
\_ sleep 10
所以从进程树的角度来看,这两个产生相同的结果:
$ bash -c 'sleep 10'$ sleep 10
这是怎么回事?
现在我的问题是:有没有办法强制中间 shell,不管传递给 bash -c ... 的表达式的复杂性如何?
(我可以将; echo; 之类的内容附加到我的实际命令中并且“有效”,但我不想这样做。有没有更合适的方法来强制中间过程存在?)
(编辑:ps 输出中的错字;删除了 cmets 中建议的 sh 标签;又一个错字)
【问题讨论】:
-
如果可能,您为什么不想要这种优化?
-
在用户可以传入任意命令的环境中处理子进程时,主要确保行为一致。我不确定绕过这个优化是我的解决方案(我遇到的实际问题必须处理 sudo 的更改:stackoverflow.com/a/34376188)。但这种行为很有趣,我想了解更多。
-
好问题。你的意思是在你的第一个 ps 树的第 2 行说
\_ bash -c sleep 10 && echo而不是\_ bash -c sleep 10 && sleep 10? -
@codeforester 确实,谢谢