「ファイルの中身があったら放置。空なら消したい」時
というシェルスクリプトを書きたい場合どうするか?
素直に考えるとこんなコードを書こうとは思わないだろうか。
ファイル演算子"-s"を使うと便利よね
if [ -s /tmp/hoge.txt ]; then
# 1バイトでも中身があれば何もしない
else
# 0バイトだったら消す
rm /tmp/hoge.txt
fi
Bourneシェルやzshを使っている場合はこれで大丈夫。ところが Bashで動かそうとするとエラー になってしまう。
Bashでは、then
やelif
、else
節の後に有効なコードを置かずに済ませることは許されないらしい。上記の例のようにコメントを置いてもダメだ。
じゃあどうする?
有効なコードがありさえすればいいので、無害なコードを置けばいい。無害かつ一番軽いコードといったら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にしておいたので見てねー。