それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

GLOBIGNORE で一時的に*(ワイルドカード)のglob 展開を止める。

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.

参考資料