根据 bash 中的循环操作退出脚本并显示错误代码
Exit script with error code based on loop operations in bash
我有一个用于 CI 管道的包装脚本,效果很好,但它总是 returns 为 0,即使 for 循环中的子命令失败。这是一个例子:
#!/bin/bash
file_list=("file1 file2 file_nonexistant file3")
for file in $file_list
do
cat $file
done
>./listfiles.sh
file1 contents
file2 contents
cat: file_nonexistant: No such file or directory
file3 contents
>echo $?
>0
由于循环的最后一次迭代成功,整个脚本以 0 退出。
我想要的是让循环在失败时继续,并在任何循环迭代返回错误时让脚本退出 1。
到目前为止我尝试了什么:
set -e
但它会在迭代失败时停止循环并退出
- 将
done
替换为 done || exit 1
- 无效
- 将
cat $file
替换为 cat $file || continue
- 无效
备选方案 1
#!/bin/bash
for i in `seq 1 6`; do
if test $i == 4; then
z=1
fi
done
if [[ $z == 1 ]]; then
exit 1
fi
有文件
#!/bin/bash
touch ab c d e
for i in a b c d e; do
cat $i
if [[ $? -ne 0 ]]; then
fail=1
fi
done
if [[ $fail == 1 ]]; then
exit 1
fi
特殊参数$?
保存最后一个命令的退出值。大于 0 的值表示失败。所以只需将其存储在一个变量中并在循环后检查它。
$?参数实际上保存了前一个管道的退出状态,如果存在的话。如果命令被信号终止,那么 $?将是 128+SIGNAL。例如 128+2 在 SIGINT (ctrl+c) 的情况下。
带有陷阱的矫枉过正解决方案
#!/bin/bash
trap ' echo X $FAIL; [[ $FAIL -eq 1 ]] && exit 22 ' EXIT
touch ab c d e
for i in c d e a b; do
cat $i || export FAIL=1
echo F $FAIL
done
我有一个用于 CI 管道的包装脚本,效果很好,但它总是 returns 为 0,即使 for 循环中的子命令失败。这是一个例子:
#!/bin/bash
file_list=("file1 file2 file_nonexistant file3")
for file in $file_list
do
cat $file
done
>./listfiles.sh
file1 contents
file2 contents
cat: file_nonexistant: No such file or directory
file3 contents
>echo $?
>0
由于循环的最后一次迭代成功,整个脚本以 0 退出。 我想要的是让循环在失败时继续,并在任何循环迭代返回错误时让脚本退出 1。
到目前为止我尝试了什么:
set -e
但它会在迭代失败时停止循环并退出- 将
done
替换为done || exit 1
- 无效 - 将
cat $file
替换为cat $file || continue
- 无效
备选方案 1
#!/bin/bash
for i in `seq 1 6`; do
if test $i == 4; then
z=1
fi
done
if [[ $z == 1 ]]; then
exit 1
fi
有文件
#!/bin/bash
touch ab c d e
for i in a b c d e; do
cat $i
if [[ $? -ne 0 ]]; then
fail=1
fi
done
if [[ $fail == 1 ]]; then
exit 1
fi
特殊参数$?
保存最后一个命令的退出值。大于 0 的值表示失败。所以只需将其存储在一个变量中并在循环后检查它。
$?参数实际上保存了前一个管道的退出状态,如果存在的话。如果命令被信号终止,那么 $?将是 128+SIGNAL。例如 128+2 在 SIGINT (ctrl+c) 的情况下。
带有陷阱的矫枉过正解决方案
#!/bin/bash
trap ' echo X $FAIL; [[ $FAIL -eq 1 ]] && exit 22 ' EXIT
touch ab c d e
for i in c d e a b; do
cat $i || export FAIL=1
echo F $FAIL
done