ksaitoの日記

日々試したことの覚え書き

シェルでファイルの差分があった場合に処理を実行したい。

シェルでファイルの差分があった場合のみ処理を実行したいユースケースがあります。 diffで差分は、検出できますが終了ステータスは0以外が返されます。 このステータスは、異常終了ではなく、差分があるか・ないかを判定したいだけなので無視して欲しいです。

いろいろな実装方法はあると思いますが、下記で意図する実装をすることができました。 シェルの||の使い方を理解する必要があるため、コードを見て意図を理解することが難しい実装なので、もっと良い方法があるような気もします。

sts=0
diff -uwB file1 file2 || sts=$?
echo Status=$sts

実行例は、以下の通りです。

$ cat sample.sh 
#! /bin/bash

sts=0
diff -uwB file1 file2 || sts=$?
echo Status=$sts
$ ./sample.sh 
Status=0
$ echo bbb > file2
$ ./sample.sh 
--- file1       2018-02-12 21:24:46.161302088 +0900
+++ file2       2018-02-12 21:26:03.922402102 +0900
@@ -1 +1 @@
-aaa
+bbb
Status=1
$ 

下記の2行目で||は、diffが失敗(終了ステータスが0以外)を返した時に実行されます。sts=$?は、必ず成功するので4行目全体として失敗することはありません。

diffが成功(終了ステータスが0)を返すとsts=$?は実行されません。 2行目のsts=0とすることで結果的にstsが未定義とならず、正常終了の0が設定されます。

ちょっと、トリッキーなので、もっと良い方法があるはずなのですが...

$ cat -n sample.sh 
     1  #! /bin/bash
     2
     3  sts=0
     4  diff -uwB file1 file2 || sts=$?
     5  echo Status=$sts
$