在 bash 中运行exec echo "some "; echo "test"
永远不会打印“一些测试”吗?
我会寻求对这个问题的确认,因为我正在编写一个小 shell 脚本,并且我希望它在exec
调用命令后不继续执行任何操作。
我想我是不用担心的,根据我的了解,咨询后:
man 3 exec
man 1p exec
shell 脚本在由 shell 执行时将使得
- shell执行程序
exec
,其中 - 使用
exec***
系列系统调用来替换正在执行脚本的 shell/bash,这样阻碍shell 的进一步操作(被“替换”)
如前所述,这个问题的主要目标是寻求对我的推理的确认,以防止echo test
执行 exec 之后发生的脚本中的任何内容(例如 )。
我希望尽可能得到一般性答案(POSIX),但以防万一,我对 GNU/Linux 和 GNU/Bash 最感兴趣
答案1
对了,如果exec
成功的话,它会替换当前的shell,所以下面的命令不会,err..执行。
然而,至少在 Bash 中,如果exec
失败:
exec [-cl] [-a name] [command [arguments]]
如果命令提供后,它会替换 shell,而不创建新进程。 [...] 如果命令由于某种原因无法执行,非交互式 shell 退出,除非
execfail
启用了 shell 选项。在这种情况下,它会返回失败。
因此,即使是类似的东西也bash -c 'exec /bin/nosuchfile; echo foo'
只会打印一条有关丢失程序文件的错误消息。要处理脚本中的错误,您需要类似的东西
#!/bin/bash
shopt -s execfail
exec /someprogram
echo whoops, it failed
但是,您仍然收到来自 的错误消息exec
。如果您对 进行重定向exec
,它仍然有效如果脚本在exec
失败后继续。
答案2
内置exec
函数(带有命令参数 1)取代了 shell 进程 2。 shell进程中的后续代码不会被执行。
exec echo "some "; echo "test"
因此,打印的唯一方法是如果在 PATH 中some text
调用了一个可执行命令,并且打印了该可执行文件而不是.在正常情况下,可执行文件的行为与名为 的命令所期望的一样,这种情况不会发生。echo
some text
some
echo
echo
echo
如果PATH 中没有调用可执行文件或者执行失败,exec
则会显示错误消息并退出 shell。即使在这种情况下,echo "test"
也不会被执行。
没有命令参数是一个不同的野兽。它不会替换 shell 进程,它只是应用重定向。
²在子shell中,只有子shell受到影响,父shell保持正常运行。 exec
答案3
exec
总是完成脚本如果它执行命令并成功执行(与命令的退出代码无关,但与启动它相关)。
exec
可以在没有命令的情况下以非常有用的方式运行:永久重定向文件描述符:
exec 3>/path/to/file
如果该命令无法启动,则 shell 行为取决于配置。bash
默认退出。
您最好使用函数来代替:
safe_exec () {
cmd="$1"
if test -z "$cmd" || ! test -f "$cmd" || ! test -x "$cmd"; then
exit 1
else
exec "$@"
fi
}
safe_exec echo "some "; echo "test"