【问题标题】:Multiple exec in a shell scriptshell脚本中的多个exec
【发布时间】:2017-01-21 23:10:52
【问题描述】:

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

#!/bin/sh

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

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

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

【问题讨论】:

标签: bash shell exec sh


【解决方案1】:

& 的使用暗示了一个子进程。

所以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'

所以第一次运行,与符号是在一个子级别

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

【讨论】:

  • 在fork shell中没有作用;它在 forked shell 中有很大的影响。
  • @chepner 哪一个??
  • 第一个;它用yes 替换在后台运行的分叉shell,而不是为了运行yes 而使用那个 shell fork,等待它完成,然后自行退出。
  • @chepner 我不确定我是否理解你的意思......这是一个叉子!?你能解释或解决一些参考资料吗?
  • @chepner shell 是后台 shell,取决于它的运行方式。无论如何,exec 或不在以&符号终止的行的开头都没有效果! (如果我错了,我将不胜感激!)
【解决方案2】:

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

【讨论】:

  • 你的解释对我来说似乎是合乎逻辑的,但我尝试启动这两个命令并将生成的进程树与“ps f”进行比较,我得到了相同的树(在这两种情况下似乎都没有成为交互式外壳和“是”之间的额外“bash”)。我又尝试了一件事:在每个命令的末尾添加“等待”。在这种情况下,我惊讶地发现“exec”有一个额外的进程(我看到两个兄弟进程表示“是”)。这和你的回答一致吗?
  • bash 可以优化为在只需要运行一个命令的子shell/子进程中自动exec。我不确定wait 的情况。
  • 我很抱歉,但在你发布参考资料解释你的意思之前,我认为这是完全错误的:即使使用dashbusybox 我的实验也倾向于告诉:有使用与号时,使用 exec 没有区别。
  • 背景是什么意思?和号 implie background 工作!关心:execnohup 不一样! stackoverflow.com/q/15595374/1765658
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 2021-06-03
  • 2020-07-09
  • 2021-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多