[Linux] 変数がワイルドカード展開されるのを無効化する方法

[Linux] 変数がワイルドカード展開されるのを無効化する方法

変数内のワイルドカードが展開される

シェルで入力を受け取ってコマンドのパラメータとして渡す形で利用するとき、ワイルドカードが展開されて予期せぬ動作が引き起こされる場合があります。

例えばカレントディレクトリが以下のようになっているとします。

.
├── 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 を実行します。

以上。

Linuxカテゴリの最新記事