BLOGTIMES
2012/11/04

rm -rf "/$hoge" のようなスクリプトで痛い目に遭わないために

  sh 
このエントリーをはてなブックマークに追加

例えば下記のようなスクリプトがあったときに DELETEFILE をセットし忘れたりすると目もあてられないような状況になります*1

DELETEFILE="path/to/file" rm -rf "/$DELETEFILE"

こういう場合、通常はこんな感じで if を使って変数が空でないか調べることになると思います。

DELETEFILE="path/to/file" if [ -n "$DELETEFILE" ] ; then rm -rf "/$DELETEFILE" fi

それでも DELETEFILE という変数に typo があったりするとやはり大惨事です。
別件で bash を調べていたら、そんなミスによる被害を軽減してくれるようなオプションを見つけたのでメモ。

set -u しよう

bash には -u というオプションがあり、これをつけておくと未定義の変数を展開する際にエラーにすることができます

man 1 bash

-u Treat unset variables as an error when performing parameter expansion. If expansion is attempted on an unset variable, the shell prints an error message, and, if not interactive, exits with a non-zero status.

こんな感じの極簡単なスクリプトで動作を確認してみます。

test.sh

#!/bin/bash echo $1

実行例

$ bash test.sh $ bash test.sh aaa aaa $ bash -u test.sh test.sh: line 3: $1: unbound variable $ bash -u test.sh aaa aaa $ bash -u test.sh ""

ちゃんと変数が未定義の場合 test.sh: line 3: $1: unbound variable というエラーで止まっていることが確認できました。ただ、エラーで止まるのはあくまで未定義の場合だけ*2なので、変数の中身のチェックは別途必要ですね。実際のコーディングの際には -u を使って bash を起動させなくてもいいように、下記のように set -u としておくクセをつけると良さそうです

#!/bin/bash set -u //ここに内容を書く
  • *1: こういう例えが適切なのかというのはあると思いますが。
  • *2: 明示的に長さゼロの文字列を指定すると通ってしまう。

トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/5345
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form

コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。

OpenID を使ってログインすることができます。

Identity URL: Yahoo! JAPAN IDでログイン