在 bash 中运行“exec echo some; echo test”永远不会打印“some test”吗?

在 bash 中运行“exec echo some; echo test”永远不会打印“some test”吗?

在 bash 中运行exec echo "some "; echo "test"永远不会打印“一些测试”吗?

我会寻求对这个问题的确认,因为我正在编写一个小 shell 脚本,并且我希望它在exec调用命令后不继续执行任何操作。

我想我是不用担心的,根据我的了解,咨询后:

  • man 3 exec
  • man 1p exec

shell 脚本在由 shell 执行时将使得

  1. shell执行程序exec,其中
  2. 使用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调用了一个可执行命令,并且打印了该可执行文件而不是.在正常情况下,可执行文件的行为与名为 的命令所期望的一样,这种情况不会发生。echosome textsomeechoecho

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"

相关内容