如何在bash中运行命令直到成功

J V*_*J V 215 bash command while-loop

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

echo "Please change password"
while passwd
do
echo "Try again"
done
Run Code Online (Sandbox Code Playgroud)

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

while `passwd`
while [[ "`passwd`" -gt 0 ]]
while [ `passwd` -ne 0 ]]
# ... And much more
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*rik 371

until passwd
do
  echo "Try again"
done
Run Code Online (Sandbox Code Playgroud)

  • oneliner:`直到passwd; 回声"再试一次"; done` (59认同)
  • 容易接受Ctr-C:`直到passwd; 回声"再试一次"; 睡2; 完成` - 所有你需要做的就是按下Ctr-C(在给定的两秒内)`echo`做了它的工作. (42认同)
  • 当Ctrl-C不能时,Ctrl-Z后跟`kill%1` (38认同)
  • 很难用Ctrl-C来解决这个问题. (18认同)
  • @azmeuk:尝试类似`直到passwd || ((count ++> = 5)); 回声"foo"; 完成`(仅限bash,如果存在变量,请务必将计数设置为0)如果需要将此计数用于普通sh,请在体内递增计数器并使用[] (8认同)
  • 多次参考这个页面后,我决定创建一个通用的bash函数来重试命令,这里是:https://gist.github.com/felipou/6fbec22c4e04d3adfae5 (2认同)

Mar*_*c B 85

您需要测试$?,这是上一个命令的退出状态.passwd如果一切正常则退出0,如果密码更改失败则退出非密码(密码错误,密码不匹配等等)

passwd
while [ $? -ne 0 ]; do
    passwd
done
Run Code Online (Sandbox Code Playgroud)

有了您的反引号的版本,你要比较passwd文件的输出,这将是这样的东西Enter passwordconfirm password等.

  • 我认为,如果您不想保留两个版本的长而复杂的命令,可以通过将第一个“passwd”更改为“/bin/false”来稍微改进这一点。 (6认同)
  • 不应该是`$?`? (2认同)
  • 我喜欢这个,因为它很清楚如何适应相反的情况。例如,运行一个具有非确定性错误的程序,直到它失败 (2认同)
  • shellcheck 失败并输出:直接使用“if mycmd;”检查退出代码,而不是间接使用 $?。[SC2181] (2认同)

duc*_*thd 58

详细说明@Marc B的答案,

$ passwd
$ while [ $? -ne 0 ]; do !!; done
Run Code Online (Sandbox Code Playgroud)

做同样事情的好方法不是命令特定的.

  • 不幸的是,这对我不起作用(我找不到'!!'命令).它应该如何工作? (10认同)
  • 这是运行上一个命令的bash技巧.例如,如果你忘记在命令前面编写`sudo`,你可以简单地执行`sudo !!`以root权限运行上一个命令. (2认同)
  • 如何在跑步之间睡觉? (2认同)
  • 如果你想将其作为别名来执行,请使用 sleep: `alias rr='while [ $? -ne 0];睡觉1;评估$(历史-p!!); 完成'` (2认同)

acl*_*kay 7

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

max_retry=5
counter=0
until $command
do
   sleep 1
   [[ counter -eq $max_retry ]] && echo "Failed!" && exit 1
   echo "Trying again. Try #$counter"
   ((counter++))
done
Run Code Online (Sandbox Code Playgroud)

  • `$command` 也不是一个很好的占位符——请参阅 [BashFAQ #50](https://mywiki.wooledge.org/BashFAQ/050) 了解为什么使用字符串存储命令本质上是不可靠的。不过,这比以前要好;撤回了反对票。 (2认同)

kur*_*umi 5

你可以使用无限循环

while true
do
  read -p "Enter password" passwd
  case "$passwd" in
    <some good condition> ) break;;
  esac
done
Run Code Online (Sandbox Code Playgroud)

  • 这是唯一不需要将我的多行命令放在函数中的答案。我在我的验证命令之后做了 `&amp;&amp; break`,而不是选择案例。 (2认同)