shell 脚本中的多次执行

问题描述 投票:0回答:2

如果 shell 脚本中有多个

exec
命令会发生什么,例如:

#!/bin/sh

exec yes > /dev/null &
exec yes alex > /dev/null

我假设仍然需要 fork 才能执行第一个命令,因为 shell 需要继续执行?

或者

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

bash shell exec sh
2个回答
2
投票

使用

&
意味着子流程。

Background Commands – &
  If a command is terminated by the control operator ampersand (&), the
  shell executes the command asynchronously – that is, the shell does not
  wait for the command to finish before executing the next command.

但是

exec
用于通过命令替换当前进程:

 exec [command arg ...]
        Unless command is omitted, the shell process is replaced with the
        specified program (which must be a real program, not a shell
        builtin or function).  Any redirections on the exec command are
       marked as permanent

所以这个功能是互斥的!在语法上:

exec bash -c 'sleep 12' &

这里

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='1'
46a47
> _='/bin/sh'

所以第一次运行,带有&符号的是在子级别

注意: 这是在许多不同的 下进行测试的。


0
投票

shell fork 来运行后台进程,但这意味着 new shell 仍然需要 fork 来运行

yes
。使用
exec
消除了子 shell 中的分叉。

© www.soinside.com 2019 - 2024. All rights reserved.