我制作了一个主 shell,一次调用多个步骤 shell
#!/bin/bash
##I'm the master shell and I'm super important. I should never fail to log.
bash ./step1.sh
bash ./step2.sh
bash ./step3.sh
bash ./step4.sh
...
在调用后一个 shell 之前,步骤 shell 不得失败。
我正在考虑 3 种方法来做到这一点,但实际上我不知道它们到底是做什么的。
方法1)
bash ./step1.sh &&
bash ./step2.sh &&
bash ./step3.sh &&
bash ./step4.sh &&
...
方法2)
bash ./step1.sh
if [ $? -eq 0 ]; then
bash ./step2.sh
fi
if [ $? -eq 0 ]; then
bash ./step3.sh
fi
if [ $? -eq 0 ]; then
bash ./step4.sh
fi
...
方法3)
set -e
bash ./step1.sh
bash ./step2.sh
bash ./step3.sh
bash ./step4.sh
...
set +e
我需要主脚本在其中一个脚本失败时立即终止step
,并且我需要能够记录失败的步骤。
哪一种是最优选的,哪一种是最安全的?
答案1
撇开“最安全”不谈,因为你从来没有说过什么行为是“安全”的,而“首选”是不知道你的脚本在做什么,很可能有“更好”的方法来实现你想要做的事情。
由于您需要在退出主脚本之前在单个步骤之一中记录失败,因此您无法真正运行这些步骤之下set -e
或之间的链中的步骤&&
。也就是说,除非step
脚本本身记录失败。
假设主脚本需要记录故障: 主脚本需要能够运行下一个脚本并检测故障。然后,它需要在终止之前通知用户此失败。
我可能会选择第二种方法的变体:
#!/bin/bash
for step in {1..4}; do
if ! bash "./step$step.sh"; then
printf 'Step %s failed, terminating...\n' "$step" >&2
exit 1
fi
done
echo 'All done, no failures'
此循环遍历整数 1 到 4,并在每次迭代中执行适当的脚本。如果脚本失败,它会向用户记录一条诊断消息,并以非零退出状态终止。
您显然可以使用而不是循环整数
#!/bin/sh
for script in ./step*.sh; do
if ! bash "$script"; then
printf 'Script "%s" failed, terminating...\n' "$script" >&2
exit 1
fi
done
echo 'All done, no failures'
...这将循环实际的步骤脚本(按照文件名通配返回它们的顺序),或者
#!/bin/bash
for script in ./step{1..4}.sh; do
if ! bash "$script"; then
printf 'Script "%s" failed, terminating...\n' "$script" >&2
exit 1
fi
done
echo 'All done, no failures'
更好地控制脚本的确切顺序(特别是如果您有超过 9 个脚本)。