如何在 bash 中一遍又一遍地运行命令直到成功?

问题描述 投票:0回答:7

我有一个脚本,想要向用户询问一些信息,但在用户填写这些信息之前,脚本无法继续。以下是我尝试将命令放入循环中以实现此目的,但由于某种原因它不起作用:

echo "Please change password"
while passwd
do
    echo "Try again"
done

我尝试了 while 循环的许多变体:

while `passwd`
while [[ "`passwd`" -gt 0 ]]
while [ `passwd` -ne 0 ]]
# ... And much more

但我似乎无法让它发挥作用。

bash command while-loop
7个回答
553
投票
until passwd
do
  echo "Try again"
done

while ! passwd
do
  echo "Try again"
done

123
投票

详细说明@Marc B的答案,

$ passwd
$ while [ $? -ne 0 ]; do !!; done

这是一种很好的方法,可以完成与命令无关的相同操作。

如果您想将其作为别名(感谢@Cyberwiz):

alias rr='while [ $? -ne 0 ]; do eval $(history -p !!); done'

用途:

$ passwd
$ rr

112
投票

您需要测试

$?
,这是上一个命令的退出状态。
passwd
如果一切正常,则以 0 退出;如果密码更改失败(密码错误、密码不匹配等...),则以非零退出

passwd
while [ $? -ne 0 ]; do
    passwd
done

使用反引号版本,您正在比较 passwd 的输出,这将是

Enter password
confirm password
等内容。


28
投票

如果有人希望有重试限制:

max_retry=5
counter=0
until <YOUR_COMMAND>
do
   sleep 1
   [[ counter -eq $max_retry ]] && echo "Failed!" && exit 1
   echo "Trying again. Try #$counter"
   ((counter++))
done

10
投票

您可以使用无限循环来实现此目的:

while true
do
  read -p "Enter password" passwd
  case "$passwd" in
    <some good condition> ) break;;
  esac
done

2
投票
while [ -n $(passwd) ]; do
        echo "Try again";
done;

0
投票

如果你想要严格模式(

set -e
)并且以上都不起作用,那就有点棘手了。

set -euo pipefail

counter=0
max_attempts=3
while ret=0; <your command> || ret=$?; [ $ret -ne 0 ]
do
  [[ $counter -eq $max_attempts ]] && echo "Command failed"; exit 1
  sleep 2
  echo "Trying again"
  counter=$((counter+1))
done
© www.soinside.com 2019 - 2024. All rights reserved.