bash / sh を使ってると glob が邪魔な時がある。
シェルスクリプトを書いていると、 *
のワイルドカードの展開がじゃまになるときが多々あります。
その都度エスケープ刷ることが多いと思います。
たとえばワイルドカードを受け取ってあとで展開するようなコマンドを作るとき
mkdir sample touch a.txt function commandA (){ GLOBIGNORE=* commandB $@ GLOBIGNORE='' } function commandB(){ echo $@ } commandA \*.txt
これを実行すると。。。
a.txt
"*.txt" を出力したいが、 途中で echo *.txt
になるので展開されてしまう。
このようにコマンドやfunctionで引数を曳き回すときにワイルドカード *
を \*
で展開させたくない。
またワイルドカードをエスケープしているときにミスってワイルドカードのファイルを作っちゃったとか
ls -l *.* *aaa* ## あああ辛い
こうやってゴミファイルを大量に作っちゃうことを防ぎたい。
GLOBIGNORE 変数をいれる。
GLOBIGNORE という変数があり、これを使うと一時的に、 ワイルドカードの展開を止めることができる。
GLOBIGNORE=*
GLOBIGNORE に書いたファイルは マッチしたものから、指定したものを除外します。
これを使うと、* を * のままエスケープなしで渡すことが出来ます。
先程の例を
GLOBIGNOREを使って無視すると・・・
function commandA (){ GLOBIGNORE=* commandB $@ GLOBIGNORE='' } function commandB(){ echo $@ }
実行すると
commandA \*.txt *.txt
このように、途中でエスケープしたり、クォートしたりしなくてもワイルドカードを渡せる。楽ができた。便利かもしれない。
関数内で使うと便利
引数を処理してべつの関数に渡すような function を書くときにワイルドカードをそのまま渡したいとき、ワイルドカードをクォートしたりクォートのクォートのクォートとか、エスケープのエスケープとか考えることが減るので楽。
もとに戻すときは
GLOBIGNORE=''
変数の内容を空にしてあげる。こ後処理を忘れると面倒になる。ワイルドカードが反応しない。glob 展開されないと焦る羽目になる。
bash のマニュアルよると
GLOBIGNORE A colon-separated list of patterns defining the set of filenames to be ignored by pathname expansion. If a filename matched by a pathname expansion pattern also matches one of the patterns in GLOBIGNORE, it is removed from the list of matches.
参考資料
- man bash