Mar*_*rco 7 linux bash shell subshell
陷入意外bash
/ sh
行为,我想知道有人可以解释其背后的基本原理,并为下面的问题提供解决方案.
在交互式bash
shell会话中,我执行:
$ bash -c 'sleep 10 && echo'
随着ps
Linux上,它看起来是这样的:
\_ -bash
\_ bash -c sleep 10 && echo
\_ sleep 10
进程树是我所期望的:
$
)bash -c ...
)但是,如果我的命令部分bash -c
是单个命令,例如:
$ bash -c 'sleep 10'
然后吞下中间的子shell,并且我的交互式终端会话在孩子处理时"直接"执行睡眠.进程树看起来像这样:
\_ -bash
\_ sleep 10
所以从流程树的角度来看,这两个产生了相同的结果:
$ bash -c 'sleep 10'
$ sleep 10
这里发生了什么?
现在我的问题是:有没有办法强制中间shell,不管传递给表达式的复杂性如何bash -c ...
?
(我可以附加类似于; echo;
我的实际命令和"工作"的东西,但我宁愿不这样做.是否有更合适的方法来强制中间过程存在?)
(编辑:ps
输出中的拼写错误;删除sh
了评论中建议的标记;还有一个拼写错误)
实际上,bash源中有一条评论描述了此功能的大部分原理:
/* 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;
}
Run Code Online (Sandbox Code Playgroud)
在这种bash -c '...'
情况下,CMD_NO_FORK
当由should_suppress_fork
函数 in 确定时,设置标志builtins/evalstring.c
.
它始终以您的利益,让外壳做到这一点.它只发生在:
这样可以节省内存,使进程的启动时间稍微快一些(因为它不需要fork
编辑),并确保传送到PID的信号直接进入您正在运行的进程,从而使sh -c 'sleep 10'
确切地确定哪个信号被杀死的父母,sleep
实际上它应该被信号杀死.
但是,如果由于某种原因你想要禁止它,你需要设置陷阱 - 任何陷阱都会:
# run the noop command (:) at exit
bash -c 'trap : EXIT; sleep 10'
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
357 次 |
最近记录: |