Bash shell脚本中的多个exec

Bash shell脚本中的多个exec,bash,shell,exec,sh,Bash,Shell,Exec,Sh,如果shell脚本中有多个exec命令,会发生什么情况,例如: #!/bin/sh exec yes > /dev/null & exec yes alex > /dev/null 我假设仍然需要fork来执行第一个命令,因为shell需要继续执行 或者&是否指定创建一个子进程,然后在其中实际运行exec?使用&意味着一个子进程 所以exec没有效果 演示: 我运行脚本:echo$$;读取foo,以防止在安静读取之前退出 在此示例中,当前进程ID为17259 当使用符号(

如果shell脚本中有多个
exec
命令,会发生什么情况,例如:

#!/bin/sh

exec yes > /dev/null &
exec yes alex > /dev/null
我假设仍然需要fork来执行第一个命令,因为shell需要继续执行


或者
&
是否指定创建一个子进程,然后在其中实际运行exec?

使用
&
意味着一个子进程

所以
exec
没有效果

演示:

我运行脚本:
echo$$;读取foo
,以防止在安静读取之前退出

在此示例中,当前进程ID为
17259

当使用符号(
&
)运行时,输出是另一个pid(更大)。当在没有符号的情况下运行时,新的shell将替换命令,并且不会分叉

将命令替换为:

sh -c 'echo $$;set >/tmp/fork_test-$$.env;read'
重新运行整个测试将在
/tmp
中生成两个文件

在我的书桌上,我可以读到:

19772
19994
19772
所以我在
/tmp
中找到了两个文件:

-rw-r--r-- 1 user0 user0 2677 jan 22 00:26 /tmp/fork_test-19772.env
-rw-r--r-- 1 user0 user0 2689 jan 22 00:27 /tmp/fork_test-19994.env
如果我运行:
diff/tmp/fork\u test-19*env
,我会读到:

29c29
< SHLVL='0'
---
> SHLVL='1'
46a47
> _='/bin/sh'
29c29
SHLVL='1'
46a47
>_u='/bin/sh'
因此,第一次运行,与安培是在一个次级


Nota:这是在许多不同的环境下测试的。

shell分叉来运行后台进程,但这意味着新shell仍然需要分叉来运行
yes
。使用
exec
消除子shell中的fork。

在forking shell中没有效果;它对分叉壳有很大的影响。@chepner哪一个??第一个;它将在后台运行的分叉shell替换为
yes
,而不是让该shell分叉运行
yes
,等待它完成,然后自行退出。@chepner我不确定我是否理解您的意思。。。是叉子!?你能解释一下或处理一些引用吗?@chepner shell是后台shell,具体取决于它的运行方式。不管怎样,在以符号结尾的行的开头有或没有执行都没有效果!(如果我错了,我希望了解更多!)您的解释对我来说似乎是合乎逻辑的,但我尝试启动这两个命令并将生成的流程树与“ps f”进行比较,我得到了这两个命令的相同树(在这两种情况下,交互shell和“yes”之间似乎没有额外的“bash”)。我又尝试了一件事:在每个命令的末尾添加“wait”。在本例中,我惊讶地发现“exec”有一个额外的进程(我看到两个同级进程表示“是”)。这与您的答案一致吗?
bash
可以优化为在只需要运行一个命令的子shell/子流程中自动执行
exec
。我不确定
wait
的情况。很抱歉,在你发布参考资料解释你的意思之前,我认为这是完全错误的:即使使用或我的实验也倾向于告诉你:在使用符号时,使用
exec
与否没有区别。背景是什么意思?符号暗指背景工作!注意:
exec
nohup
不同!考虑你的问题是否被回答了!
29c29
< SHLVL='0'
---
> SHLVL='1'
46a47
> _='/bin/sh'