如果在shell脚本中有多个exec
命令,会发生什么情况,例如:
#!/bin/sh
exec yes > /dev/null &
exec yes alex > /dev/null
我认为为了执行第一个命令仍需要fork,因为shell需要继续执行?
或者&
是否指定创建一个实际运行exec的子进程?
答案 0 :(得分:2)
使用&
会影响子流程。
所以exec
没有效果。
演示:
export LANG=C
echo $$
17259
exec sh -c 'echo $$;read foo' &
[1] 17538
17538
[1]+ Stopped exec sh -c 'echo $$;read foo'
fg
exec sh -c 'echo $$;read foo'
17259
我运行脚本:echo $$;read foo
以便在安静地读取上一个输出之前阻止退出。
在此示例中,当前进程ID为 17259
。
使用&符号(&
)运行时,输出是另一个pid(更大)。在没有&符号的情况下运行时,新shell替换命令并且不是 forked 。
通过以下方式替换命令: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_test-19*env
,我读:
29c29
< SHLVL='0'
---
> SHLVL=http://stackoverflow.com/posts/41785560/edit'1'
46a47
> _='/bin/sh'
所以第一次运行,&符号位于 sublevel 。
Nota:这是在许多不同的shell进行测试的。
答案 1 :(得分:-1)
shell分支运行后台进程,但这意味着 new shell仍然需要fork来运行yes
。使用exec
消除了子shell中的fork。