shell scriptのif文まとめ!


こんにちは、@s_tsukaです。

今回はshell scriptのif文のまとめです。この記事を読めば一発で書きたいifを書けるようにすることを目的とします。

経緯

みなさんは普段shell scriptを書いていますか?自分は月に数回程度書いています。便利にするためのscriptだったり、プロダクトコードとしてのscriptだったり、JenkinsのビルドJobやバッチJobのscriptだったり。

そんなとき、高確率でif文を書きますが、いつもifの書き方を忘れてしまいます。C, Java, Scalaなどはちゃんと覚えているのですが、shell scriptはどうしても覚えられなくて・・・そんなわけでまとめていきます。

でもまとめと言えど、すでにまとめてくれているサイトは山ほどあるわけで・・・特にココとかはよくまとまっています。

if 文と test コマンド

なので、本当に必要な部分だけまとめていこうと思います。

実際に使う文や機能

以下淡々と載せていきます。シェバン(#!/bin/bashは省略します)

[[

たまに見かける(一部の人はよく使う)bashキーワードである[[です。基本的にはこれを使います。変数展開による事故を防止できるためです。ちなみに[[ですが、日本語名とかわかりませんよね。自分は「かっこかっこ」とか呼んでますが・・・

どうやら英語でも正式名称は無いようですが「double brackets」と呼ばれているようです。

文字列一致

val=foo
if [[ $val = "foo" ]]; then
  echo "一致 val=$val"
fi

# 出力
# 一致 val=foo

普通に=使えば良いだけ。

[[を使っておけば変数展開の事故を防げるので、

if [[ $aaa = "foo" ]]; then
  echo ""
else
  echo "変数が存在しなくても[[組み込みコマンドなら正しく動く aaa=$aaa"
fi

# 出力
# 変数が存在しなくても[[組み込みコマンドなら正しく動く aaa=

こんなのも正しく動きます(変数aaaは定義なし)

数値一致

val=1
if [[ $val = 1 ]]; then
  echo "一致 val=$val"
fi

# 出力
# 一致 val=1

こちらも普通に=を使えば良いだけ。

これは一見数値の比較に見えますが、$val = “1”でも一致するので、その点は注意・・・だけど実際書いてるとそれほど型は意識しないので、大丈夫かな?

一致しない(否定)

上記では 「a = b」というように書いていますが、もちろん「a != b」と書けばOKです。

数値の大小比較

# if(val >= 1)
val=1
if [[ $val -ge 1 ]]; then
  echo "1以上 val=$val"
fi

# 出力
# 1以上 val=1

ここは少し曲者ですね。-geで「以上」になります。>=は使えません。

geとleで混乱する人は「geは A(左辺)は、B(右辺)より大きいまたはイコール(greater than or equal to)」とストレートに覚えておくと良いと思います。geとgt両方あって分からない・・・という人はe = equalと覚えましょう。

本当は>=というワードが使えれば良いのですけども。

少し飛ばしましたが、

ge : 以上

gt : より大きい

le : 以下

lt : より小さい

ですが、gt, ltについては>, <というおなじみの不等号が使えますので覚えなくても大丈夫です。

ファイルの存在チェック

touch tmp.txt
if [[ -e tmp.txt ]]; then
  echo "存在する"
fi

# 出力
# 存在する

existのeで覚えておけば良いと思います。

文字列の長さ(長さ0か1以上か)

val=foo
if [[ -n $val ]]; then
  echo "0より長い val=$val"
fi

# 出力
# 0より長い val=foo

val=
if [[ -z $val ]]; then
  echo "長さ0 val=$val"
fi

# 出力
# 長さ0 val=

nかzです。これは少々覚えづらいですね。non zero lengthのn、zero lengthのzで覚えると良いかと思います。

ファイルサイズが0より大きいか、あるいは0か

echo "abc" > tmp.txt
if [[ -s tmp.txt ]]; then
  echo "中身あり"
fi

# 出力
# 中身あり

rm tmp.txt && touch tmp.txt
if [[ ! -s tmp.txt ]]; then
  echo "中身なし"
fi

# 出力
# 中身なし

-sを使えばOKです。sizeのsです。

AND, OR, NOT

if [[ 1 = 1 && 2 = 2 || 3 != 4 ]]; then
  echo "複合"
fi

-aや-oは覚える必要はありません。プログラマならばよくある表記通り&&, ||, !で覚えておけば良いです。

細かいオプションを忘れたとき

この記事をあらためて見返しても良いですし、Google検索しても良いですし、man testコマンドを打って説明を読んでも良いと思います。

まとめ

shell scriptのifで重要なポイントだけを説明しました。

みなさんのShell scriptコーディングが少しでも捗れば幸いです。