TL; DR
shell スクリプトの場合
# エラーコード 1 を無視
cmd.sh ||exit$(($?-1))# 複数のエラーコードを無視したい場合 (下記は 1, 2 を無視)
cmd.sh || sh -c"exit $(($?-1))"|| sh -c"exit $(($?-1))"Makefile の場合
TARGET:# エラーコード 1 を無視
cmd.sh||exit$$(($$?-1))# 複数のエラーコードを無視したい場合 (下記は 1, 2 を無視)
cmd.sh||sh-c"exit $$(($$? - 1))"||sh-c"exit $$(($$? - 1))"はじめに
shell スクリプトや Makefile の処理で、「このエラーは処理を続けてほしいんだけど」みたいなこと、たまにありますよね。
sh だと
cmd.sh ||true# エラーコードが常に 0 になるMake だと
TARGET:# 頭の "-" で、エラーを無視するようになる
-cmd.shとかやると、エラーを無視してくれますが、あらゆるエラーが無視されます。そうなると、想定外のエラー発生時にも処理が進んでしまうので、できれば特定のエラー時だけ無視するようにしたいところです。
そこで
# エラーコード 1 を無視
cmd.sh ||exit$(($?-1))1のところを別の数値にすれば、好きなエラーコードを指定することができます。
||は、前のコマンドがエラーコード 1 以上で終わった場合に、後ろのコマンドを実行するようにします。$?で直前のコマンドのエラーコードとり、$(( ))で計算ができるので、1 を引いて、それを新しいエラーコードにしています。
これで、もしエラーコードが 1なら新しいエラーコードが 0になって、正常とみなされ処理が継続される、その他のエラーコードならやはり非 0なので、エラーで停止する、という寸法です。
Makefile でも基本的に同じです。$$としないと sh のコマンドに $が渡らないので、そこだけ注意です。
TARGET:# エラーコード 1 を無視
cmd.sh||exit$$(($$?-1))応用編: 複数のエラーコードを無視したい
複数のエラーコードを正常としたいときも、同じものをつなげていけばOK、、、なのですが、少し一工夫して sh -c "..."でくくってあげましょう。そうしないと、最初の exitで処理が終わってしまい、意図した動作になりません。
# 複数のエラーコードを無視したい場合 (下記は 1, 2 を無視)
cmd.sh || sh -c"exit $(($?-1))"|| sh -c"exit $(($?-1))"また、2 つめ以降の $?には、それまでの計算が反映された値が入るので、そこには注意が必要です。上の例の場合、2つめの exitも -1してますが、一つ前ですでに 1引かれているので、最初のエラーコードが 2の場合に、ここで 0となります。
cmd.sh || sh -c"exit $(($?-1))"|| sh -c"exit $(($?-2))"とすると、エラーコード 1, 3を無視することになります。
あとがき
わりとよくあるニーズな気がするのですが、少しググってもページを見つけられなかったので、書いてみました。
「もっとよいやり方があるよ!」という方、ぜひ教えてもらえるとありがたいです 