反复运行shell命令,直到失败?


190

我写了一个模糊测试,失败了。我添加了一些调试代码,但是现在我想运行测试直到失败,这样我才能收集调试输出。

我已经设置了测试,因此可以使用以下命令运行它:

./runtest

我当前的解决方案是编写一个untilfail脚本:

#!/bin/bash
$@
while [ $? -eq 0 ]; do
    $@
done

然后使用它:

untilfail ./runtest

有没有更简单的解决方案?


11
旁注:习惯上引用“ $ @”。
jordanm 2012年

Answers:


326

while 需要执行一条命令,因此您可以使用更简单的命令

while ./runtest; do :; done

./runtest返回非零退出代码(通常表示失败)时,这将停止循环。

但是,为了进一步简化当前的解决方案,您只需将您的untilfail脚本更改为如下所示:

#!/bin/bash

while "$@"; do :; done

然后,您可以使用任何已在使用的命令来调用它:

untilfail ./runTest --and val1,val2 -o option1 "argument two"

25
最好指出这[是一个命令。这是新用户的一种常见的误解[是部分ifwhile语法。
jordanm 2012年

2
我如何计算它在失败之前运行了多少次?
GrantJ

13
@GrantJ:这实际上非常简单。放置count=0在循环之前,然后放置在循环中(而不是:循环(无操作)),(( count++ ))这会使计数器递增。
nneonneo

14
生产力骇客:如果您使用的系统上装有say扬声器,并且您可以在扬声器while ./runtest; do :; done && say test failed停止运行时得到通知
Schneems,2016年

5
@Schneems:值得注意的say是特定于macOS的。
nneonneo

13

如果您不想将复杂的管线包装到Shell脚本或函数中,则可以这样做:

while true; do 
  curl -s "https:..." | grep "HasErrors.:true"
  if [[ "$?" -ne 0 ]]; then 
    break
  fi
  sleep 120
done

在这种情况下,HTTP请求始终返回200,但在出现错误时也会返回一些具有属性“ HasErrors”:true的JSON。


1

在一个系统中有一个类似的问题,该系统的Shell重试逻辑到处都是重复的,我做了一个专门的工具来解决这个问题,称为“ retry”:

retry --until=fail ./runtest

一个更复杂的示例:

retry --until=fail --message="test succeeded" --delay=1 ./runtest

可从https://github.com/minfrin/retry获得该工具。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.