script1
我们从脚本运行脚本script_main
script_main
:
#!/bin/bash
/tmp/script1
echo $?
sleep 2
echo script ended
script1
:
#!/bin/bash
exit 1
显而易见,script1
退出代码为 1,但主脚本将继续执行直至结束。
我的问题:什么时候有可能script1
立即exit 1
停止main_script
?
答案1
最直接的方法是exit
在其他脚本失败时显式使用第一个脚本。将脚本执行置于条件中,例如
otherscript.sh || exit 1
或者
if ! otherscript.sh ; then
ret=$?
echo "otherscript failed with exit code $ret. exit." >&2
exit 1
fi
这将允许主脚本进行任何它想要的清理,或者只是尝试一些其他解决方案,可能取决于子进程的退出代码是什么。在第一个中,我们可以仅使用|| exit
, 来传递子进程的退出代码。
如果你想让主脚本退出任何命令启动失败,然后set -e
.
set -e
otherscript.sh
echo "this will not run if otherscript fails"
set -e
不适用于在条件构造内运行的程序,因此我们仍然可以测试特定代码或尾随它们以|| true
忽略失败。但现在退出点无处不在,我们可以trap somecmd EXIT
在 shell 退出之前进行任何清理,无论它发生在哪里。
让内部脚本强制主脚本退出也是可能的,但有点不友好,您不会期望通常的应用程序会这样做。但是,如果您愿意,只需让内部脚本简单地拍摄其父进程是一种方法:
$ cat mainscript.sh
#!/bin/bash
./otherscript.sh
echo "$0 exiting normally"
$ cat otherscript.sh
#!/bin/bash
echo "$0 kill $PPID"
kill $PPID
$ bash mainscript.sh
./otherscript.sh kill 11825
Terminated
在这里,如果您otherscript.sh
从交互式 shell 运行,它将尝试拍摄交互式会话。SIGTERM
不过,我测试的所有 shell 在交互运行时似乎都会忽略这种情况。无论如何,主 shell 可以再次trap
使用SIGTERM
.
kill 0
您可以使用杀死运行的进程组中的所有进程,而不是仅捕获父进程otherscript.sh
。如果从非交互式 shell 启动,通常会包括父进程。
答案2
你可以来源script 2
。喜欢:
. /tmp/script1.sh
将从中读取退出代码,script2
这将终止进程。
➜ /tmp cat script.sh
#!/bin/bash
echo "Running ${0} with pid $$"
. /tmp/script1.sh
echo $?
echo "This code won't execute"
sleep 2
echo "Script ${0} ended"
echo "This code won't execute"
sleep 2
echo "Script ${0} ended"
➜ /tmp cat script1.sh
#!/bin/bash
echo "Running ${0} with pid $$"
exit 5
运行它:
➜ /tmp ./script.sh
Running ./script.sh with pid 10306
Running ./script.sh with pid 10306
➜ /tmp echo $?
5