我正在寻找一种有效的方法来做到这一点。
我有各种命令需要按顺序执行;如果第一个命令失败,第二个命令就无法运行,依此类推。
我确实循环遍历了它们;但是循环必须遍历每个命令,这不是我需要做的。
例如,如果有 3 个命令:a、b 和 c;a 始终运行,b 仅在 a 成功运行时运行,c 仅在 b 成功运行时才运行,但如果 b 失败一次,则必须从 a 重新开始
LOOP *****************************
until a; do
echo "a failed, retrying"
sleep(3)
done
until b; do
echo "b failed, need to start all over"
b_failed=1
break
START FROM THE BEGIN OF LOOP ***************
done
until c; do
echo "c failed, need to start all over from a"
c_failed=1
break
START FROM THE BEGIN OF LOOP ***************
done
.... OTHER INSTRUCTIONS
LOOP *****************************
我尝试使用常规循环,但 break 会从子循环退出,而不会从头开始。我想进入这个主循环,执行第一个操作直到它通过,然后执行第二个;如果失败,则从循环顶部开始,而不运行所有其他命令等等。虽然我似乎找不到正确的方法来做到这一点,除非我用大量的 if-else 检查每个命令来膨胀逻辑。
有没有一种简洁的方法可以用几行代码来做到这一点?
编辑:将“until”改为“while”;进行了更正
EDIT2:非常感谢您的解决方案!虽然必须对其进行修改,因为我无法按原样运行它:if 缺少 fi 来终止命令,并且缺少“then”语句。我无法在 if 中运行 do;所以这是对我有用的:
while true; do
until a; do
echo "a failed, retrying"
sleep(3)
done
if [ ! b ]; then
echo "b failed, need to start all over"
continue
else
c
fi
if [ ! c ]; then
echo "c failed, need to start all over from a"
continue
else
break
fi
done
答案1
一个非常简单的解决方案,正如 Squeezy 部分提到的:
until a && b && c; do
:
done
&&
是逻辑与运算符。它确实会短路,因此只有当左侧表达式为真时,右侧表达式才会被求值。
&&
完整表达式(或 s 链)的返回值&&
是最后一个求值表达式的结果。因此,如果此处三个命令中的任何一个失败,后面的命令将被忽略,并且将until
看到 afalse
并进入其主体,不执行任何操作(:
只是无操作来填充循环主体),然后a && b && c
再次循环回到测试条件。如果所有三个都成功,那么until
将看到 atrue
并结束。
因此,这对于简单情况来说很好,但如果您想打印这些状态消息,则不太好。使用||
(逻辑或)和是可能的{ }
,但会非常混乱。
如果您想在命令失败时做一些额外的事情,例如回显状态消息,这样做会更好:
while true; do
until a; do
echo "a failed, retrying"
sleep(3)
done
if [ ! `b` ]; then
echo "b failed, need to start all over"
continue
fi
if [ ! `c` ]; then
echo "c failed, need to start all over from a"
continue
fi
break
done
continue
返回到封闭循环的开始处。在返回到封闭循环的开始处后放置一个数字会n
提升级别。虽然这里没有必要,因为它们在if
s 内而不是循环内。顺便说一句,break
同样会取一个数字并跳出n
封闭循环。
如果您希望保持外观不变,该a
部分也可以是if [ ! a ];
而不是 循环。在这种情况下,until
您需要添加。continue