bash中“exec”和“exit”之间的区别

时间:2012-01-16 00:21:43

标签: bash exec exit

我已经看到bash脚本中使用“exit”和“exec”来在发生错误时停止脚本执行。例如:

if [ ! -f file ]; then
echo "no file"
exit 1
fi

if [ ! -f file ]; then
exec echo "no file"
fi

这里的最佳做法是什么?为什么?关于“exec”和“exit”的更广泛的讨论/解释也是受欢迎的:)

3 个答案:

答案 0 :(得分:14)

exit只退出shell,将指定的数字退出代码(如果省略则返回0)返回到父进程。它等同于名为exit的C库例程,或从main返回。

exec 用新的可执行映像替换 shell(仍然在同一进程中运行),这将在适当的时候退出并返回一些代码或其他代码到父进程。它大致相当于C库例程execvp

您的第一个示例几乎(但不完全)是在发生错误时停止脚本的正确方法。它应该读

if [ ! -f file ]; then
    echo "no file" >&2
    exit 1
fi

您的示例中缺少的>&2会导致错误消息转到它所属的stderr,而不是stdout,它不属于它。

你的第二个例子是错误的。除了错误信息发送到错误的地方之外,exec echo将停止脚本(因为/bin/echo将执行其操作然后退出)但它将返回退出代码0到父进程。退出代码0表示成功。在Unix环境中运行的程序必须始终确保在失败时返回非零退出代码。

exec的正确使用是在shell脚本中进行一些设置工作,然后调用用另一种语言编写的长期程序,之后没有任何事情要做,所以没有必要保持shell进程闲置。例如:

#! /bin/sh
PATH=/special/directory/for/foo:$PATH
export PATH
exec foo

答案 1 :(得分:3)

命令exit使用给定的退出代码退出当前shell。命令exec用参数定义的新进程替换当前shell。这也有效地在进程终止后终止脚本,退出代码是新进程的退出代码。

第一个代码片段调用内部shell命令echo,然后使用退出代码1终止shell。第二个代码用外部程序echo替换shell,它可能会以退出代码0。

我肯定会推荐第一个变体。它保存了启动外部命令/bin/echo并使用退出代码正确指示错误。

答案 2 :(得分:0)

指示错误的正确方法是脚本返回非零代码,例如1。 在您的情况下,最好的方法是使用“退出1”。

使用“exec”只会执行后面的代码。也许您看到的示例使用“#!/ bin / bash -e”或“set -e”,然后使用“exec”调用失败的代码,从而导致“exec”本身返回非零代码,“ - e”表示如果任何命令返回非零代码或计算结果为false,则立即退出脚本。