199
178

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でif~then~else~fi文使う場合に忘れちゃならないこと

Posted at

「ファイルの中身があったら放置。空なら消したい」時

というシェルスクリプトを書きたい場合どうするか?
素直に考えるとこんなコードを書こうとは思わないだろうか。

ファイル演算子"-s"を使うと便利よね
if [ -s /tmp/hoge.txt ]; then
  # 1バイトでも中身があれば何もしない
else
  # 0バイトだったら消す
  rm /tmp/hoge.txt
fi

Bourneシェルやzshを使っている場合はこれで大丈夫。ところが Bashで動かそうとするとエラー になってしまう。
Bashでは、thenelifelse節の後に有効なコードを置かずに済ませることは許されないらしい。上記の例のようにコメントを置いてもダメだ。

じゃあどうする?

有効なコードがありさえすればいいので、無害なコードを置けばいい。無害かつ一番軽いコードといったらnullコマンド:ではないかと思う。したがって、こう書けばよい。

nullコマンド(3行目)を置けばBashでも安全に動く
if [ -s /tmp/hoge.txt ]; then
  # 1バイトでも中身があれば何もしない
  :
else
  # 0バイトだったら消す
  rm /tmp/hoge.txt
fi

ん、nullコマンドを使ったら戻り値が保存されないって?

大丈夫、[ … ] を通る時点でそもそも保存されないので気にしなくてOK。

いや、そもそも条件を反転すれば……

そうね、[ ! -s /tmp/hoge.txt ]とすればelse節要らないよね。

でも、次の場合なんかはnullコマンド使う方が簡単よね。

世の中いつも型通りにいくとは限らない
size=$(wc -c /tmp/hoge.txt | awk '{print $1}')
if [ $size -eq 0 ]; then
  # ファイルサイズ0なら、ゴミなので安心して削除
  rm /tmp/hoge.txt
elif [ $size -eq 100 ]; then
  # ファイルサイズ100バイトなら、正常なのでここでは何もせず次へ進む。
  :
else
  # ファイルサイズがこれ以外なら、おかしいのでエラー終了
  echo 'Invalid file!' 1>&2
  exit 1
fi

というわけで覚えておきたいマメ知識だと思う。

まとめTipsも追記&バージョンアップ

どの環境でも使えるシェルスクリプトを書くためのメモというまとめTipsにもこの話を追記して、バージョン1.4にしておいたので見てねー。

199
178
5

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
199
178

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?