Bash:在源脚本中停止错误

sle*_*ica 9 bash shell

在要执行的shell脚本中,我可以使用中止错误set -e.

但是,在源脚本中,set -e如果稍后的命令以错误状态退出,则使用将终止原始shell.

source set_e.sh
./exit_1.sh
# shell dies
Run Code Online (Sandbox Code Playgroud)

一个简单的解决方案是set +e在脚本的最后,但是set -e如果使用的话,这将破坏父级(如果有人将来包装我的脚本,这很可能会发生).

如何在源脚本中获得错误中止功能?

kon*_*box 5

不可能。但是,如果需要,您可以选择使用子外壳程序:

(
    set -e
    source another.sh
)
Run Code Online (Sandbox Code Playgroud)

只有调用脚本的环境永远不能被调用脚本更改。

注意:用换行符将两个命令分开并且不要使用分号可能很重要。


gal*_*axy 5

好吧,问题不是很清楚:原始作者在拦截源脚本中的错误后想要什么,但是,作为解决方案的入口点,以下内容就足够了:

您可以在 ERR 上设置陷阱并在那里处理源脚本中的错误。下面是两种情况:一种是使用“set -e”的源脚本,另一种是不使用“set -e”的源脚本。

主脚本使用定义的“set -e”调用辅助脚本并捕获错误:

[galaxy => ~]$ cat primary.sh
#!/bin/sh

set -e
echo 'Primary script'
trap 'echo "Got an error from the secondary script"' ERR
source secondary.sh
trap - ERR
echo 'Primary script exiting'
[galaxy => ~]$ cat secondary.sh
#!/bin/sh

echo 'Secondary script'
set -e
echo 'Secondary script generating an error'
false
echo 'Secondary script - should not be reached'
[galaxy => ~]$ ./primary.sh
Primary script
Secondary script
Secondary script generating an error
Got an error from the secondary script
[galaxy => ~]$
Run Code Online (Sandbox Code Playgroud)

主脚本在没有“set -e”的情况下调用辅助脚本并捕获错误:

[galaxy => ~]$ cat primary.sh
#!/bin/sh

set -e
echo 'Primary script'
trap 'echo "Got an error from the secondary script"' ERR
source secondary.sh
trap - ERR
echo 'Primary script exiting'
[galaxy => ~]$ cat secondary.sh
#!/bin/sh

echo 'Secondary script'
echo 'Secondary script generating an error'
false
echo 'Secondary script - should not be reached if sourced by primary.sh'
[galaxy => ~]$ ./primary.sh
Primary script
Secondary script
Secondary script generating an error
Got an error from the secondary script
[galaxy => ~]$
Run Code Online (Sandbox Code Playgroud)

作为奖励:拦截源脚本中的错误并继续:

[galaxy => ~]$ cat primary.sh
#!/bin/sh

echo 'Primary script'
i=0
while [ $i = 0 ]; do
    i=1
    trap 'echo "Got an error from the secondary script"; break' ERR
    source secondary.sh
done
trap - ERR
echo 'Primary script exiting'
[galaxy => ~]$ cat secondary.sh
#!/bin/sh

echo 'Secondary script'
echo 'Secondary script generating an error'
false
echo 'Secondary script - should not be reached if sourced by primary.sh'
[galaxy => ~]$ ./primary.sh
Primary script
Secondary script
Secondary script generating an error
Got an error from the secondary script
Primary script exiting
[galaxy => ~]$
Run Code Online (Sandbox Code Playgroud)


buf*_*uff 0

您可以检测是否set -o在源脚本开头设置了 errexit 选项,并在源脚本末尾恢复其原始值。