Skip to main content

なにが 真 なのか - Bash 版

といっても哲学的な話ではない

結論だけ先に書く

if の判定が通るものが true だとすると、結論はこう。

bash
if <コマンド>; then
echo "コマンドの終了コードが 0 ならこっち"
else
echo "コマンドの終了コードが 0 以外ならこっち"
fi

使いうるパターン

シェルスクリプト内で使うパターンとしては、このような感じか。

bash
if command; then  # 終了コードで判定
bash
command
x=$?
if [ $x -eq 0 ]; then # 終了コードで判定
bash
x=`command`  # 標準出力を文字列に入れている (終了コードではない)
if [ "$x" = "xxx" ]; then
bash
x=true   # 一見、true をセットしているように見えるが、true というコマンド名を入れてるだけ
if $x; then

前提知識

ややこしいので、前提となる知識を列挙する。

前提知識1. 終了コード

直前のコマンドの終了コードは $? で取得可能

  • 成功 : 0
  • 失敗 : 非0
bash
ls > /dev/null
echo $? # => 0

ls /no/such/file 2> /dev/null
echo $? # => 1
  • 余談:
    • デバッグ用に echo $? などとすると、次に取得時は echo の終了コードになる
    • ので、変数に入れたい場合は必ず直後に入れること
bash
ls /no/such/file 2> /dev/null
echo $? # => 1
result=$? # ← よくやる間違い。echo の終了コード 0 が入る

if [ $result -eq 0 ]; then # ← よって、常に通ってしまう
echo "Success!"
fi

前提知識2. test コマンド または [ .. ]

[ .. ] の構文は test コマンドといって、
=, -eq などの比較演算子を評価して終了コードを見るもの。

bash
test "a" = "b"
echo $? # => 1

[ "a" = "b" ]
echo $? # => 1

[ .. ] と Bash 固有の [[ .. ]] の詳細については別の機会に

前提知識3. true, false コマンド

  • true, false は コマンドで、終了コードがそれぞれ 0, 1
  • 反転演算子 ! が使える
bash
true
echo "$?" # => 0

false
echo $? # => 1

! true
echo $? # => 1
  • 余談
    • true, false は bash のビルトインコマンド ( which true とやると分かる )
    • Mac だと(というよりファイルシステムに大文字小文字区別がないと)、TRUE でも true でも /usr/bin/true を実行する ( 紛らわしい・・ )

前提知識4. true, false の代入

代入したらただ文字列となるだけ

bash
T=true
F=false

echo $T
echo $F

前提を踏まえて if 文を再度見る

bash
if $x; then

このような判定をしたいとして、

bash
if true; then
echo "かならずこっちを通る"
fi
bash
if 0; then  # 0 というコマンドは無いと出て $? が 1
:
else
echo "かならずこっちを通る"
fi