失敗するまで繰り返しシェルコマンドを実行しますか?


190

私が書いたファジーを信頼性の低い失敗をテストを作成しました。デバッグコードを追加しましたが、テストが失敗するまで実行して、デバッグ出力を収集したいと思います。

以下を使用して実行できるように、テストをセットアップしました。

./runtest

私の現在の解決策はuntilfailスクリプトを書くことです:

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

次にそれを使用します:

untilfail ./runtest

より簡単な解決策はありますか?


11
補足:習慣的に "$ @"を引用してください。
ヨルダン2012年

回答:


326

while コマンドを実行して実行するので、よりシンプルな

while ./runtest; do :; done

これにより./runtestゼロ以外の終了コード(通常は失敗を示す)が返されたときにループが停止します。

ただし、現在のソリューションをさらに簡略化するには、untilfailスクリプトを次のように変更するだけです。

#!/bin/bash

while "$@"; do :; done

そして、あなたはすでに使用しているコマンドでそれを呼び出すことができます:

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

25
それ[がコマンドであることを指摘するのも良いことです。これは、新しいユーザーとの一般的な誤解だ[の一部であるifwhile構文。
ヨルダン2012年

2
失敗する前に何回実行したかをどのようにカウントできますか?
GrantJ 2015年

13
@GrantJ:実際には本当に簡単です。count=0ループの前に置いて、ループの代わりに:(何もしない)、入れてください(( count++ ))-これはカウンターをインクリメントします。
nneonneo

14
生産性のハック:sayスピーカー付きのシステムを使用while ./runtest; do :; done && say test failedしている場合、スピーカーが停止した場合に通知を受けるために使用できます
Schneems

5
@Schneems:saymacOS固有であることは注目に値します。
nneonneo

13

複雑なパイプラインをシェルスクリプトまたは関数にラップしたくない場合は、次のように機能します。

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

この場合のHTTPリクエストは常に200を返しますが、エラーが発生すると、属性 "HasErrors":trueを持つJSONも返します。


1

シェルの再試行ロジックがどこにでも複製されているシステムで同様の問題があったため、これを解決するための専用ツールを「再試行」と呼びました。

retry --until=fail ./runtest

より複雑な例:

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

https://github.com/minfrin/retryから入手可能なツール。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.