Bashでアスタリスク文字列を設定ファイルから読み込む場合、アスタリスクがワイルドカードパターンと認識され変数展開されてしまいます。アスタリスクを文字列として扱いたい場合に、どのようにすれば変数展開されずに済むかについてまとめました。
この記事できること
- BashでGLOBIGNORE変数を使用することでglobを有効化したり、無効化したり制御ができるようになります。
- Bashでワイルドカードを文字列として扱う場合とそうでない場合の使い分けを正しく理解できるようになります。
ワイルドカードパターンのおさらい
コマンド
/tmp/testディレクトリ配下にアスタリスクを指定すると、隠しファイルを除くすべてのファイルが表示されます。
ls -l /tmp/test/*
出力結果
-rw-r--r-- 1 ingktds wheel 0 2 22 03:27 /tmp/test/aaa
-rw-r--r-- 1 ingktds wheel 0 2 22 03:27 /tmp/test/bbb
-rw-r--r-- 1 ingktds wheel 0 2 22 03:27 /tmp/test/ccc
この様なワイルドカードパターンをglob(グロブ)と言うようです。私もPerlを勉強して初めて知った用語です。
globとは
globとは
glob, globfree – パターンにマッチするパス名を見付ける。glob() によっ て確保されたメモリ領域を解放する。
デフォルトの動作
test.conf
例えばこの/tmp/test/*というパスを記述した設定ファイル(test.conf)を読み込むbashスクリプト(test.sh)の動作を見てみましょう。test.confは/tmp/test/*のパスが書かれているだけのシンプルなファイルです。
/tmp/test/*
test.shも同じでtest.confの内容を一気に読み取って配列LINEに代入してechoしているだけです。
#!/bin/bash
CONF=test.conf
LINE=(`cat $CONF`)
echo ${LINE[*]}
コマンド
bash test.sh
出力結果
どうやらbashがglobの機能を如何なく発揮して(アスタリスク)を変数展開してしまったようです。
/tmp/test/aaa /tmp/test/bbb /tmp/test/ccc
アスタリスクのエスケープ後の動作
test.conf
じゃあどのようしてアスタリスクを文字列として認識させるかというと、皆さんまず始めに思いつくのがtest.confの*(アスタリスク)をエスケープすることだと思います。
/tmp/test/\*
コマンド
bash test.sh
出力結果
/tmp/test/\*
test.pl,test.shともに同じ実行結果になりましたが、期待している文字列と違っています。test.confのglobをいちいちエスケープするのも面倒くさいし、そもそも期待している動作と違います。やっぱりtest.confはそのままでやりたい。
GLOBIGNORE変数設定後の動作
test.conf
/tmp/test/*
こんなときはGLOBIGNOREシェル変数に*を代入してしまえば、globの変数展開は無視されます。使い終わったら必ずunsetしてあげましょう。じゃないと以降の動作にも影響が出てしまいます。
#!/bin/bash
CONF=test.conf
GLOBIGNORE=*
LINE=(`cat $CONF`)
echo ${LINE[*]}
unset GLOBIGNORE
コマンド
bash test.sh
出力結果
/tmp/test/*
まとめ
- デフォルトの動作では設定ファイルに書かれたワイルドカードは変数展開されてしまいます。
- ワイルドカードはエスケープできないです。
- GLOBIGNORE変数を使うことで対象のワイルドカードを文字列として扱うことができます。
コメント