ユーニックス総合研究所

  • home
  • archives
  • bash-if

Bashのif文の書き方: [とtestの違い

  • 作成日: 2020-08-25
  • 更新日: 2023-12-24
  • カテゴリ: Bash

Bashのif文の書き方

Bashではif文を使うことができます。
これは特定の条件の時に処理を分岐させたいときに使われる文です。

Bashのif文は↓のように使います。

i=1  

if [ $i == 0 ]; then  
    echo "zero"  
elif [ $i == 1 ] && [ $i -lt 2 ]; then  
    echo "one"  
else  
    echo "other"  
fi  

実行結果。

one  

if文の構造

Bashのif文は↓のような構造になっています。
「判定」部分のコマンドの結果が0ならthen~fi内の「処理」を実行し、0以外なら処理を実行しません。

if 判定; then  
    処理  
fi  

また、セミコロンを付けない場合は↓のように書くことが出来ます。

if 判定  
then  
    処理  
fi  

「判定」部分にはtestコマンドを渡します。

# 1が1ならtrue  
if test 1 -eq 1; then  
    echo "true"  
fi  

実行結果。

true  

testコマンドの使い方

testはファイルまたは値を比較し、オプションの条件にマッチすれば0を、マッチしなければ0以外を終了値として返すコマンドです。
たとえば2つの値が等しいかチェックしたい時は-eqオプションを使います。

# 1と1は等しい(eq)?  
test 1 -eq 1  
echo $?  
# 0  

# 0と1は等しい(eq)?  
test 0 -eq 1  
echo $?  
# 1  

ほかにも↓のようなオプションがあります。

# 1と0は等しくない?  
test 1 -ne 0  
echo $?  
# 0  

# 2は1以上?  
test 2 -ge 1  
echo $?  
# 0  

# 2は1より上?  
test 2 -gt 1  
echo $?  
# 0  

# 1は2以下?  
test 1 -le 2  
echo $?  
# 0  

# 1は2より下?  
test 1 -lt 2  
echo $?  
# 0  

特に文字列の比較では==!=を使います。

test "abc" == "abc"  
echo $?  
# 0  

test "abc" != "def"  
echo $?  
# 0  

testには他にも様々なオプションがあります。
詳しくはman testでマニュアルを参照してください。

testの代わりに`[`を使う

testと同じような振る舞いをするコマンドに[があります。
このコマンドは末尾の]を無視します。
よって[を使うとif文を↓のように書けます。

if [ 1 -eq 1 ]; then  
    echo "true"  
fi  

実行結果。

true  

[testのエイリアスのように見えますが、別のコマンドです。Ubuntuなどでは/usr/bin/[にバイナリが置かれています。

結果を反転する

testの結果を反転するには!を使います。

test ! 1 -eq 1  
echo $?  

実行結果。

1  

if文と[を使う場合は↓のように書くことが出来ます。

if [ ! 1 -eq 0 ]; then  
    echo "!!!"  
fi  

実行結果。

!!!  

elif

if文にはelifを繋げることが出来ます。
これは「1つ前のif文の結果が0(真)でなかったら実行するif文」と言えます。

if [ 0 -eq 1 ]; then  
    echo "0 is 1"  
elif [ 1 -eq 1 ]; then  
    echo "1 is 1"  
fi  

実行結果。

1 is 1  

elifは1つのif文に何個でも繋げることが出来ます。

if false; then  
    echo "false 1"  
elif false; then  
    echo "false 2"  
elif true; then  
    echo "true"  
fi  

実行結果。

true  

else

if文にはelseを繋げることが出来ます。
elseは1つのif文に1つまで付けることが出来ます。
elseは「if文の結果がどれも0(真)でなかったら実行する文」と言えます。

if false; then  
    echo "false 1"  
elif false; then  
    echo "false 2"  
else  
    echo "else!"  
fi  

実行結果。

else!  

if文とtrueとfalse

truefalseコマンドはそれぞれ終了値を0, 1で返すコマンドです。

true  
echo $?  
# 0  

false  
echo $?  
# 1  

これらのコマンドを使えばif文にtruefalseを指定することが出来ます。

if true; then  
    echo "true!"  
fi  
# true!  

if false; then  
    echo "false!"  
else  
    echo "else!"  
fi  
# else!  

if文と変数

test[コマンドには変数を渡すことも出来ます。

i=0  

if [ $i -eq 0 ]; then  
    echo $i  
fi  

実行結果。

0  

AND

2つのコマンドの結果からANDの論理値を得たい場合は↓のように&&で繋げます。

i=2  

if [ $i -ge 1 ] && [ $i -le 3 ]; then  
    echo "1 <= $i <= 3"  
fi  

実行結果。

1 <= 2 <= 3  

これは「変数iの値が1以上かつ3以下なら」というif文になります。

OR

2つのコマンドの結果からORの論理値を得たい場合は↓のように||で繋げます。

i=1  

if [ $i -eq 0 ] || [ $i -eq 1 ]; then  
    echo "0 or 1"  
fi  
0 or 1  

これは「変数iの値が0または1なら」というif文になります。

使用例

if文の使用例です。

偶数ならnyan, 奇数ならwan

for文でカウント変数をカウントし、カウント変数が偶数ならnyan, 奇数ならwanを表示するサンプルです。

for ((i=0; i<4; i++)); do  
    if [ $((i % 2)) -eq 0 ]; then  
        echo "nyan"  
    else  
        echo "wan"  
    fi  
done  

実行結果。

nyan  
wan  
nyan  
wan  

終了しますか? 続行しますか?

終了しますか?(y/n)」というプロンプトを表示し、yが入力されたらループを終了するサンプルです。

while true; do  
    echo "終了しますか?(y/n)"  
    read line  

    if [ $line == "y" ]; then  
        echo "終了します"  
        break  
    elif [ $line == "n" ]; then  
        echo "続行します"  
    else  
        echo "不正な入力です"  
    fi  
done  

実行結果。

終了しますか?(y/n)  
n  
続行します  
終了しますか?(y/n)  
a  
不正な入力です  
終了しますか?(y/n)  
y  
終了します  

ファイルは存在する?

ファイルの存在確認はtest-eオプションを使います。
また、結果を反転させるには!を使います。

fname1="a.sh"  
fname2="b.sh"  

if [ -e $fname1 ]; then  
    echo $fname1は存在します  
fi  

if [ ! -e $fname2 ]; then  
    echo $fname2は存在しません  
fi  

実行結果。

a.shは存在します  
b.shは存在しません  

問題

Q1: if文に繋げられる文節を答えよ

  1. try
  2. elif
  3. else

Q2: testで文字列の比較に使えるオプションを答えよ

  1. ==
  2. -eq
  3. !=

Q3: testの終了値がnのときif文は真と評価する。nの値を答えよ

  1. 1
  2. 2
  3. 0

正解

Q1: 2, 3
Q2: 1, 3
Q3: 3