Bash 循环直到某个命令停止失败
Posted
技术标签:
【中文标题】Bash 循环直到某个命令停止失败【英文标题】:Bash loop until a certain command stops failing 【发布时间】:2016-05-26 12:24:25 【问题描述】:我想在 bash 中编写一个循环,该循环一直执行到某个命令停止失败(返回非零退出代码),如下所示:
while ! my_command; do
# do something
done
但是在这个循环中我需要检查返回的退出代码my_command
,所以我尝试了这个:
while ! my_command; do
if [ $? -eq 5 ]; then
echo "Error was 5"
else
echo "Error was not 5"
fi
# potentially, other code follows...
done
但随后特殊变量?
在循环体内变为0
。
显而易见的解决方案是:
while true; do
my_command
EC=$?
if [ $EC -eq 0 ]; then
break
fi
some_code_dependent_on_exit_code $EC
done
如何检查循环体内my_command
(在循环头中调用)的退出代码,而无需使用带有上述中断条件的while true
循环重写此示例?
【问题讨论】:
离题了。这里是the same question on Unix.SE。 【参考方案1】:除了众所周知的while
循环之外,POSIX 还提供了一个until
循环,无需否定my_command
的退出状态。
# To demonstrate
my_command () read number; return $number;
until my_command; do
if [ $? -eq 5 ]; then
echo "Error was 5"
else
echo "Error was not 5"
fi
# potentially, other code follows...
done
【讨论】:
当你知道有一个until
循环时非常明显! RTFM 给我。我认为最好的答案。【参考方案2】:
如果true
命令伤害了你的感受,你可以这样写:
while my_command ; ret=$? ; [ $ret -ne 0 ];do
echo do something with $ret
done
这可以简化:
while my_command ; ((ret=$?)) ;do
echo do something with $ret
done
但如果您不需要 ResultCode,您可以简单地:
while my_command ; [ $? -ne 0 ];do
echo Loop on my_command
done
或
while my_command ; (($?)) ;do
echo Loop on my_command
done
也许,为什么不呢?
while ! my_command ;do
echo Loop on my_command
done
但是从那里你可以更好地使用until
as chepner suggest
【讨论】:
好答案!我从来不知道while command1; command2 ; do ...
有效
到目前为止对我来说似乎是赢家。我喜欢!【参考方案3】:
您可以从PIPESTATUS
内置变量中获取否定命令的状态:
while ! my_command ; do
some_code_dependent_on_exit_code "$PIPESTATUS[0]"
done
chepner 的解决方案在这种情况下更好,但 PIPESTATUS
有时对类似问题很有用。
【讨论】:
好点。我不知道PIPESTATUS
也适用于这种情况。【参考方案4】:
所以在我的情况下,我还需要忽略一些退出代码并希望为用户提供一些有用的输出,所以我写了这个:
retrycmd()
MSG=$1
IGNORE=$2
shift 2
local SLEEP_T=5
local L_CNT=5
local C_CNT=0
while ((C_CNT++ < $L_CNT)) && ! $@;do
RET=$PIPESTATUS[0]
#echo "RET: $RET"
for I in $IGNORE//,/ ;do # bashism: replace(/) all(/) match(,) with(/) value(<space>)
if (($RET == $I));then
#echo "$RET = $I"
break 2
fi
done
echo "$MSG failure $C_CNT"
sleep $SLEEP_T
done
if (($C_CNT > $L_CNT));then
echo "$MSG failed"
poweroff
fi
#retrycmd "Doing task" "IGNORE,CSV" <CMD>
retrycmd "Ping google" "0" ping www.google.com
【讨论】:
以上是关于Bash 循环直到某个命令停止失败的主要内容,如果未能解决你的问题,请参考以下文章