我的bash脚本类似于:
{
# Try block
command 1
command 2
command 3
} || {
# Catch errors
while true; do
{
# Try block inside
# Change parameters for command 1, command 2
command 1
command 2
command 3
break
} || {
# Change parameters and try again
continue
}
done
}
或多或少这段代码工作得很好,但是......
由于某种原因,try
部分的工作效果与我预期不符。如果我的一些命令没有返回0
代码,我认为它失败了,但事实并非如此。
对于某些特定情况,我的command 2
会在第一个try块中返回1
个代码,但它不会失败并进入catch
部分,command 3
从此处执行try
阻止,就是这样。
这是我的问题:
如何处理bash中的错误?只是玩回报代码?
更新:
原始代码看起来非常类似于:
主要思想是所有3个命令都应该逐个执行,并且所有这些命令都与folder_name
有某种关系。
folder_name=my_folder
suffix=0
{
cd /home/test/
mkdir $folder_name
ls -la $folder_name
} || {
while true; do
suffix=$(expr $suffix + 1)
{
folder_name=$folder_name_$suffix
cd /home/test/
mkdir $folder_name
ls -la $folder_name
break
} || {
continue
}
done
}
答案 0 :(得分:1)
正如您可能已经知道的那样,您可以使用set -e
(== set -o errexit
)来简化错误处理,方法是让脚本在未经测试的失败时中止。
不幸的是,非exec的子shell的行为与exec-ed shell子行为不同,因为非exec的子shell可以看到它是否经过测试,而exec'd shell子则不能。
因此,这个:
#!/bin/sh -e
echo "EXEC'D SHELL CHILD"
if sh -e <<'EOF'
true(){ echo true; return 0; }
false(){ echo false; return 1; }
true
false
true
true
EOF
then
echo SUCCESS
else
echo FAILED: $?
fi
echo ===========
echo "NON-EXEC'D SUBSHELL"
if (
true(){ echo true; return 0; }
false(){ echo false; return 1; }
true
false
true
true
)
then
echo SUCCESS
else
echo FAILED: $?
fi
输出:
EXEC'D SHELL CHILD
true
false
FAILED: 1
===========
NON-EXEC'D SUBSHELL
true
false
true
true
SUCCESS
(可以随意使用/ bin / bash代替/ bin / sh - 它的行为完全相同)
因此,您可以使用set -e
来简化错误处理,但在测试的子shell(或块或函数)中仍需要&&
或|| return 1
,或者您需要使用exec'd贝壳儿童代替。在您的情况下,您可以这样做:
sh -ec' command 1
command 2
command 3' || ...
或
{ comman 1 && command 2 && command 3; } || ...
答案 1 :(得分:1)
我在这里看到两个问题。
使用大括号对命令进行分组时,必须最后是分号(或结束大括号前的换行符)。请参阅docs here
另一方面,您还没有考虑返回代码。您通常会使用[[ $? -eq 0 ]]
之类的内容检查返回代码。但在这里,您可以使用&&
简单地链接命令。
e.g。
{
cd /home/test/ &&
mkdir $folder_name &&
ls -la $folder_name;
}
但是,以下将做你需要的。
cd /home/test/
prefix=my_folder
suffix=0
folder_name="$prefix"
while true; do
if [[ -e $folder_name ]]; then
folder_name="${prefix}_$((++suffix))"
continue
fi
mkdir "$folder_name"
if [[ $? -ne 0 ]]; then
echo "mkdir failed"
exit 1
fi
break
done