変数内のワイルドカードが展開される
シェルで入力を受け取ってコマンドのパラメータとして渡す形で利用するとき、ワイルドカードが展開されて予期せぬ動作が引き起こされる場合があります。
例えばカレントディレクトリが以下のようになっているとします。
.
├── foo.txt
└── hoge.txt
この状態で以下のように *
を echo
するとワイルドカード展開されてファイルが表示されてしまいます。
$ echo *
foo.txt hoge.txt
例えばこれが変数に入った値だとします。
$ x='*'
$ echo $x
foo.txt hoge.txt
こんな感じで変数に入っているワイルドカード *
が展開されてしまいます。
ワイルドカードを展開しないようにダブルクォーテーションで変数を括る
変数内のワイルドカードを展開しないようにするには変数をダブルクォーテーションで括るとよいです。
$ x='*'
$ echo $x
foo.txt hoge.txt
# ワイルドカード展開をしない
$ echo "$x"
*
単純に変数を参照するときに $x
みたいにするとワイルドカード展開してしまうので、ダブルクォーテーションで括って "$x"
とすると、展開されません。
ワイルドカードは即時展開される?
ダブルクォーテーションで括るやり方でうまくいきそうですが、関数の引数を参照するときにはうまくいきませんでした。
$ echo *
foo.txt hoge.txt
$ function hoge() { echo "$1"; }
$ hoge *
foo.txt
これは引数で渡して実行している個所 hoge *
の時点でワイルドカードが展開され、hoge foo.txt hoge.txt
となっているためです。ワイルドカードは参照時にすぐに展開されていることがわかります。
参照時にクォートで括れば展開されずに渡すことができます。
$ hoge '*'
*
$ hoge "*"
*
set -f でワイルドカード展開を無効化する
$ set --help | grep -- -f
-f Disable file name generation (globbing).
上記のヘルプを見てもらえばわかるようにワイルドカードの展開を無効にする設定があります。set -f
で無効化できます。
# ワイルドカード展開無効化
$ set -f
$ echo *
*
# ワイルドカード展開有効化
$ set +f
$ echo *
foo.txt hoge.txt
無効化した設定は後続の処理でも有効なので、再度展開を有効化したいときは set +f
を実行します。
以上。
コメントを書く