我有一个bash脚本script.sh
,如:
./step1.sh
./step2.sh
./step3.sh
每个步骤* .h脚本都返回正确的错误代码,无论它们是否失败。
现在如果step3.sh失败,我会得到一个合适的退出代码,但是如果step1.sh或step2.sh失败并且step3.sh成功,那么我得到status = 0,这是不理想的。
我知道我可以使用
set -e
在我的脚本顶部,如果任何中间步骤失败,脚本将失败,但这不是我想要的。
我想知道是否有一个简单的选项可用于执行每个中间脚本(即使其中一个失败)但返回退出代码>如果其中任何一个失败而无需手动跟踪每个退出代码,则为0。
答案 0 :(得分:5)
您可以捕获错误:
#!/bin/bash
echo "test start."
trap 'rc=$?' ERR
./error.sh
./script2.sh
echo "test done."
return ${rc}
有关陷阱如何工作的详细信息,请参阅trap。
答案 1 :(得分:0)
你可以这样做:
#!/bin/bash
# array with all the scripts to be executed
arr=(./step1.sh ./step2.sh ./step3.sh)
# initialize return status to 0
ret=0
# run a loop to execute each script
for i in "${arr[@]}"; do
echo "running $i"
bash "$i"
ret=$((ret | $?)) # return status from previous step bitwise OR with current status
done
echo "exiting with status: $ret"
exit $ret
答案 2 :(得分:0)
我知道你曾说过你不想维护每个退出代码,但这对于数组来说实际上很容易:
declare -a rcs
./step1.sh ; rcs+=($?)
./step2.sh ; rcs+=($?)
./step3.sh ; rcs+=($?)
然后你可以简单地循环遍历数组,寻找你想要的第一个(或最大,最后,平均,总和等)错误代码。下面的代码显示了如何执行此操作以返回遇到的第一个错误:
for ((idx = 0; idx < ${#rcs[@]}; idx++)); do
[[ ${rcs[$idx]} -ne 0 ]] && return ${rcs[$idx]}
done
return 0
同样,要获取最大的错误:
rc=0
for ((idx = 0; idx < ${#rcs[@]}; idx++)); do
[[ ${rcs[$idx]} -gt $rc ]] && rc=${rcs[$idx]}
done
return $rc
答案 3 :(得分:0)
归结为绝对基础,
rc=0
./step1 || rc=$?
./step2 || rc=$?
./step3 || rc=$?
exit $rc