Twitterボケっと見てたところ、指定したコマンド失敗時にリトライをする方法についてのツイートが流れてきたので、個人的にちょっと調べてみた。

回数制限を付けない場合

回数制限を付けない(失敗したらずっとリトライをし続ける)のであれば、untilでやるのが一番短く書けそうだ。

until COMMAND;do sleep 1;done

例えば、こんな感じでやると、成功するまでは1秒ごとにリトライをする。

[root@BS-PUB-CENT7-01 ~]# until mkdir $(date +%Y%m%d_%H%M00);do sleep 1;done
mkdir: ディレクトリ `20170615_043200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_043200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_043200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_043200' を作成できません: ファイルが存在します
[root@BS-PUB-CENT7-01 ~]# 
[root@BS-PUB-CENT7-01 ~]# ls -la 20170615_043300
合計 4
drwxr-xr-x.  2 root root    6  6月 15 04:33 .
dr-xr-x---. 14 root root 4096  6月 15 04:33 ..
[root@BS-PUB-CENT7-01 ~]# ls -lad 20170615_043300
drwxr-xr-x. 2 root root 6  6月 15 04:33 20170615_043300

回数制限を付ける場合

Twitterで見かけたのはコレなのだが、リトライ回数に制限を付ける場合だと、素直にforを使うのが一番わかりやすい+短く書けるみたいだ。

for i in {1..10};do COMMAND&&break;sleep 1;done
[root@BS-PUB-CENT7-01 ~]# for i in {1..10};do mkdir $(date +%Y%m%d_%H%M00)&&break;sleep 1;done
[root@BS-PUB-CENT7-01 ~]# for i in {1..10};do mkdir $(date +%Y%m%d_%H%M00)&&break;sleep 1;done
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します
mkdir: ディレクトリ `20170615_074200' を作成できません: ファイルが存在します

ちなみに、untilで書くとちょっと複雑になってしまうようなのであまりオススメはしない。

(i=0;until COMMAND||[ $i -eq 5 ];do sleep 1;((i++));done)