3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Bash の短絡評価・非短絡評価

Posted at

株式会社オズビジョンのユッコ (@terra_yucco) です。
監視スクリプトなどをはじめ、LAMP でサービスやっている企業でも Bash を書く機会はまだまだたくさんあります。
そんな中、複数条件で判断するとき、短絡評価なのか?非短絡評価なのか?が気になったので調べてみた。

短絡評価

短絡評価とは、

  • A == 真
  • B == 真

の命題があった場合において、

  • A || B

を判断する場合、B 側の判断を行わないような評価方法のことを言います。
A と B どっちかが真ならば条件を満たすので A が真である時点で B 側は見ない、非常に効率的です。

ちなみに && においても同様であり

  • A == 偽
  • B == 偽

の命題があった場合において、

  • A && B

を判断する場合、やはり B 側の判断は行われません。上記と同じロジックによるものです。

Bash における条件判断

実態は test コマンドですが、スクリプト内では以下の書き方をすることが (少なくとも私は) 多いです。

#!/bin/bash -u
if [ ! -f /path/to/file ]; then
    echo 'NG'
    exit 1
fi
echo 'OK'
exit 0

複合条件の場合に短絡評価と非短絡評価をする方法を考えてみます。
特定の日だけファイルの行数をチェックし、それ以外の日は一律 OK とするような処理を例にします。

短絡評価

以下のようにそれぞれの条件式を [] で分割し && 演算子でつなぐことで短絡評価になります。

minimal.sh
#!/bin/bash -u
if [ $( date +%Y%m%d ) -eq 20190601 ] && [ $( cat /path/to/file | wc -l ) -eq 1 ]; then
    echo 'NG'
    exit 1
fi
echo 'OK'
exit 0

1 つ目の評価式に記載した date は実行されていますが、2 つ目の評価式に記載したファイルのチェックは行われていません。

$ bash -x minimal.sh
++ date +%Y%m%d
+ '[' 20190613 -eq 20190601 ']'
+ echo OK
OK
+ exit 0

非短絡評価

1 つの [] の中に評価式を入れ -a でつなぐことで非短絡評価になります。

non-minimal.sh
#!/bin/bash -u
if [ $( date +%Y%m%d ) -eq 20190601 -a $( cat /path/to/file | wc -l ) -eq 1 ]; then
    echo 'NG'
    exit 1
fi
echo 'OK'
exit 0

実際に cat も呼び出され、エラーなども発生していることがわかります。

$ bash -x non-minimal.sh
++ date +%Y%m%d
++ cat /path/to/file
++ wc -l
cat: /path/to/file: そのようなファイルやディレクトリはありません
+ '[' 20190613 -eq 20190601 -a 0 -eq 1 ']'
+ echo OK
OK
+ exit 0

man test の記載

bash バージョン

$ bash --version
GNU bash, バージョン 4.2.46(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

man の該当項目

       EXPRESSION1 -a EXPRESSION2
              both EXPRESSION1 and EXPRESSION2 are true
       EXPRESSION1 -o EXPRESSION2
              either EXPRESSION1 or EXPRESSION2 is true

これを見ると、評価が短絡かどうかは明記されていないので、もしかしたら系に依存するかもしれません。

Conclusion

[ EXPRESSION1 ] && [ EXPRESSION2 ] は短絡評価
[ EXPRESSION1 -a EXPRESSION2 ] は非短絡評価

手が覚えているレベルでよく使う Bash の評価式でしたが、この 2 つの書き方に評価の違いがあるということは調べてみて初めて知りました。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?