bash + 如何同时从辅助脚本和主脚本退出

bash + 如何同时从辅助脚本和主脚本退出

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

相关内容