背景
diffは2つのファイルを比較し、その差分を表示するコマンドです。
diffコマンドの終了ステータスは、次の3パターンです。
-
0: 差分なし -
1: 差分あり -
2以上: エラー
今回、GitHub Actions内で二つのファイルの差分を出力しようとしたところ、この仕様によりGitHub Actionsが失敗扱いになってしまいました。
単に差分だけを表示したい場合、差分がある場合も正常終了となるのが望ましいです。
この記事では、diffコマンドの終了ステータスを書き換えるスクリプトを、自分用のスニペットも兼ねて紹介します。
コード
#!/bin/bash
diff -u old new >> /dev/stdout || exit_code=$?
if [[ $exit_code = 1 ]]
then
:
else
(exit $exit_code)
fi
解説
diff -u old new >> /dev/stdout || exit_code=$?
まず、diffコマンドが「差分あり(終了ステータス1)」または「エラー(終了ステータス2以上)」を返した場合に、その終了ステータスをexit_code変数に保存します。
||はシェルスクリプトの演算子で、左側のコマンドが失敗した場合のみ右側のコマンドが実行されます。
$?は一つ前のコマンドの終了ステータスが格納されている変数で、今回は0以外が入ります。
if [[ $exit_code = 1 ]]
then
:
else
(exit $exit_code)
fi
終了ステータスが1の場合は何も処理を行わず(:)、それ以外はステータスコードをexitコマンドに渡して終了します。
diffが正常終了していた場合、exit_codeは空なので、ステータス0で終了します。
それ以外のdiffコマンドのエラーの場合は、そのエラーコードがexitコマンドにそのまま渡されます。
もし差分がない場合をエラーにしたい場合は、exit_codeが空の場合の条件分岐を追加してください。
終了ステータス
差分あり => 正常終了
--- old 2024-08-06 10:23:00
+++ new 2024-08-06 09:43:12
@@ -0,0 +1 @@
+a
$ echo $?
0
差分なし => 正常終了
echo $?
0
ファイルが存在しない => エラー
diff: old: No such file or directory
$ echo $?
2
終わりに
diffコマンドに限らず、シェルスクリプト内でコマンドの通常の終了ステータスを書き換えたい状況は時々発生します。
diffコマンドは特に、終了ステータスが他のコマンドと比べて独特なため、参考になれば幸いです。