多値終了ステータステスト(成功または失敗だけでなく)

多値終了ステータステスト(成功または失敗だけでなく)

file1="/scratch/abc/osx.xrts"のような2つのファイルがありますfile2="/scratch/unzip/abc/osx.xrts"

diff行末を無視してコマンドを実行しています。コマンドとコードは次のとおりです。

diff --strip-trailing-cr file1 file2 > /dev/null
if [ $? -eq 0 ]; then
  echo "no diff"
elif if [ $? -eq 1 ]; then
  echo "there is diff"
else
  echo "something is wrong"
fi

観察結果

これにより、内容file1file2内容が同じであれば、「違いなし」という結果が得られます。ただし、問題はコンテンツfile1とコンテンツの間にわずかな違いがある場合に発生します。file2この場合、diff上記のようにコマンドを実行し、違いを印刷して終了します。 if-else部分にはまったく入らない。

for多くのファイルを比較する必要があるため、このコードをループ(ここでは表示されていません)として実行しています。しかし、私のスクリプトは違いを印刷して違いがある最初のファイルのペアを見つけるとすぐに終了し、if-else部分にはまったく到達しません。何が間違っているのかわかりません。どんな助けでも大変感謝します。

私が期待する結果

ファイル間に違いがある場合は、違いを印刷しないでください。代わりに、そのセクションに移動してelif if [ $? -eq 1 ]; then「違いがあります」を印刷してから、他のファイルを比較してforループを続行する必要があります。

ベストアンサー1

マイナーな印刷上のエラーを修正した後、コードは次のようになります。

(1)      diff --strip-trailing-cr "$file1" "$file2" > /dev/null
(2)      if [ $? -eq 0 ]; then
(3)        echo "no diff"
(4)      elif [ $? -eq 1 ]; then
(5)        echo "there is diff"
(6)      else
(7)        echo "something is wrong"
(8)      fi

(もちろん、上記の画像の行番号は説明のためのものであり、スクリプトの一部ではありません。)これには誰も指摘していない微妙なバグがあります。終了状態が何であれ、  diff その  echo "something is wrong"部分は決してそうではありません。達した。diffコマンドを、、など(exit "$1") の数字に置き換えてから、引数として渡すことで簡単にテストできます。0123

問題は、これが$?揮発性変数であることです。もちろん、2行はdiff1行()コマンドの終了状態です。ただし、4行目は $?2行目のテストコマンドの終了状態です[ $? -eq 0 ]。終了状態がdiff0でない場合、[ $? -eq 0 ]テストは$?1に設定されます。いつもthere is diffニュースを受けました。

この問題を処理する方法はいくつかあります。 1つは、終了状態を安定したdiff変数に保存することです。

diff --strip-trailing-cr "$file1" "$file2" > /dev/null
diff_exit_status=$?
if [ "$diff_exit_status" -eq 0 ]; then
  echo "no diff"
elif [ "$diff_exit_status" -eq 1 ]; then
  echo "there is diff"
else
  echo "something is wrong"
fi

もちろん、より短い変数名を使用することもできます。

2番目は、  case次の文を使用することです。

diff --strip-trailing-cr "$file1" "$file2" > /dev/null
case "$?" in
  (0)
      echo "no diff"
      ;;
  (1)
      echo "there is diff"
      ;;
  (*)
      echo "something is wrong"
esac

おすすめ記事