俺のメモ帖

とあるインフラ系SEのメモ帖。趣味や技術的なもとか書けたらいいなぁ。

戻り値で結果を判定する場合に注意が必要なコマンド(tarやping)

バッチファイルやシェルスクリプトを作る際、コマンドの結果を戻り値で判定することは多々あると思う。

ただし、いくつかのコマンドは注意が必要な場合がある。

その例を2つほど示す。

  1. WindowsPINGコマンド
    お馴染みのネットワーク疎通確認コマンド。
    大抵は、戻り値が0だったら疎通OKって組むと思う。
    だけどこれはNG。実は戻り値0でも失敗する場合もある。

    ①成功の場合(戻り値=0)

    f:id:infrase:20180622171420j:plain

    ②失敗の場合(戻り値≠0)

    f:id:infrase:20180622171614j:plain

    ここまではよくあるパターン。大抵はこの2つを戻り値で分岐させて生存監視としている。
    でも、実は次のようなパターンも存在する。
    ③失敗の場合(戻り値=0)

    f:id:infrase:20180622171726j:plain
    宛先に到達できていないのに戻り値が0で返ってきている。

    じゃあ戻り値以外でどうやって判断するか?
    確実にそうとは言えないんだけど、以前居たプロジェクトでは標準出力の文字列で判断させた。
    日本語版のPING(WindowsXP以降のPING?)だと、正常な場合は『ラウンド トリップの概算時間 (ミリ秒):』という文字列が出力されるようだ。
    なので、以下のようにFINDとかと組み合わせて実行する。

    f:id:infrase:20180622172758j:plain

    ほかにも、「XXXからの応答」の後ろにバイト数・時間・TTLなんかが表示されていればOKっぽいので、それでもよいのかも。

  2. Linuxのtarコマンド
    こちらもお馴染みのコマンド。だけど、こっちも単純に戻り値0かそうでないかで判定すると、失敗する場合がある。
    それは、アーカイブ中にアーカイブ対象のファイルが更新された場合、警告が発生して、戻り値が1で返ってくる場合があることだ。
    そもそも、アーカイブ実行時に、対象ファイルを更新したりなんてことは、普通は行わないと思う。
    だけど、この前居たプロジェクトでは、何かまでは判別できなかったけど、稀にアーカイブ中に対象ファイルが更新されたという警告が出力されて、戻り値1で返ってきてジョブがこける事があった。
    それで、tarコマンドのことを色々調べた結果、これは特に問題ないため、戻り値1は正常終了扱いとして処理を継続するように修正した。

    一応、大きいファイルを準備して、そのファイルをアーカイブしている最中に、ファイルに追記を行う試験をしてみたところ、アーカイブされたファイル自体は、追記を行う前の状態だったため、問題がないと結論付けた。

    このときは結局、何が対象ファイルを更新しているかまでは追及しなかったんだけど、これを追及するとなると、「inotify」や「fanotify」とかで対象ファイルやディレクトリを監視しなければいけないので、結構面倒である。

 

以上、戻り値で結果を判定する場合に注意が必要なコマンドについて。

このメモはそういう事象があるたびに更新していくことにしようと思う。

 

 

仕事に使えるLinuxシェルスクリプト~bashで作る実用サンプル41

仕事に使えるLinuxシェルスクリプト~bashで作る実用サンプル41

 

少しでも参考になれば。