Bashでループをn回繰り返す方法


9

以下のようなシナリオがあります:

if [file exists]; then
   exit   
elif
   recheck if file exist (max 10 times)
   if found exit else recheck again as per counter  
fi 

これはシェルの非常に基本的な機能です。あなたもそれを研究しましたか?
ペシュケ2018

はい。しかし、私のコードから期待される出力が得られません。また、できるだけ
簡潔

1
@Peschke、まあ、彼らは少なくとも何が必要ですか、3つの基本的な機能(ループ、条件、ファイルのテスト、ループからの脱出)。少なくとも問題は、それがそうであるように非常に明確です。それはロッキーが試みたもののスケッチを含むことができましたが、とにかく誰かがそれをとにかく答えで完全に書き直すでしょう。;)
ilkkachu 2018

回答:


9

このループを行うには多くの方法があります。

ksh93構文(もでサポートされているzshbash):

for (( i=0; i<10; ++i)); do
    [ -e filename ] && break
    sleep 10
done

POSIXのようなシェルの場合:

n=0
while [ "$n" -lt 10 ] && [ ! -e filename ]; do
    n=$(( n + 1 ))
    sleep 10
done

どちらのループも、ファイルの存在を再度テストする前に、各反復で10秒スリープします。

ループが終了したら、ファイルの存在を最後にテストして、ループが10回実行されたために終了したのか、ファイルが表示されたために終了したのかを調べる必要があります。

必要に応じて、inotify-toolsにアクセスできる場合は、sleep 10呼び出しを

inotifywait -q -t 10 -e create ./ >/dev/null

これは、現在のディレクトリでファイル作成イベントが発生するのを待ちますが、10秒後にタイムアウトします。このようにして、指定されたファイル名が出現すると(出現した場合)、ループが終了します。

完全なコードはinotifywaitsleep 10必要ない場合はに置き換えて)、次のようになります。

for (( i=0; i<10; ++i)); do
    [ -e filename ] && break
    inotifywait -q -t 10 -e create ./ >/dev/null
done

if [ -e filename ]; then
    echo 'file appeared!'
else
    echo 'file did not turn up in time'
fi

inotifyを使用すると、ループ全体をほぼ置き換えることができます。ファイルが存在するかどうかをテストし、存在しない場合は、100秒間inotifywaitしてください。ほとんど、ファイル以降に作成することができ、単にテストとはinotifyの間、および...タイムアウトする前に、あなたは完全な100秒間眠りたい
ilkkachu

1
@ilkkachuはい、それは良い考えですが、ここではinotifywait、のドロップイン代替品として使用していますsleep
クサラナンダ

8

カウントが変数でない場合は、ブレース展開を使用できます。

for i in {1..10}   # you can also use {0..9}
do
  whatever
done

カウントが変数の場合、seq次のコマンドを使用できます。

count=10
for i in $(seq $count)
do
  whatever
done

ファイルが見つからない場合のみループしたい(最大10回)。見つかった場合は3回目と言ってから正常に終了します
Rocky86

@ Rocky86:これは、xenoidによって提案されたソリューションと矛盾しません。誰も最後まで数えることを強制しません....
user1934428

私はこれが好きです$(seq $count)
ワーカー

0
n=0
until [ "$((n+=1))" -gt 10 ]
do    <exists? command exit
done
echo oh noes!

test -e file && exitより柔軟ですが


なぜ疑問符ですか?リダイレクトのターゲットでのグロブの動作は、シェルによって異なることに注意してください。
ステファンChazelas

2
それは例えば、FIFOのために(例えばLinux上の/ dev /ウォッチドッグへのシンボリックリンクで悪化し)非常に悪いことができ、ファイルを開くの副作用があることに注意してください
ステファンChazelas

Bashの場合でも、これはファイルのようなものを探しexists1ますが、一致するファイルが見つからない場合は、多くのエラーを出力します。(また、複数の一致がある場合はエラーになります。)私がテストした他のシェルは、いずれにせよエラーを与えるようです...
ilkkachu

@ikkachu-ええ。それはちょっとポイントだった。エラーが発生した場合、スクリプトは報告します。stderrを抑制する必要がある場合は、抑制しdone 2<>/dev/nullます。ないbashことは、スクリプトのでしょうか?私はそれが-iインタラクティブな状況でそれを効果的にするだけだと思った。それでも、exists?と同じくらいフィラー名fileです。しかし、ええ、私は嫌いリダイレクトで引用-ネジ場合はそう 多くのアップ。
mikeserv

@Stéphane-本当に理由はありません。しかし、ええ、fifos、判読不能...それが私が指摘しtest -eた理由です。
mikeserv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.