前に Bash の Glob に関するエントリを書きました。
他にも Glob には様々な応用があります。 あまり知られていないような使い方も多いので、それらをご紹介していくコーナーです。
extglob
Glob で正規表現と not 条件を表現できるようになる。 詳細については、
に書きました。
nullglob
通常、Glob を指定したもののそれが合致するファイル/ディレクトリが存在しない場合、Bash は指定した Glob をファイル名として解釈します。 何を言っているかというと、これを見れば分かって頂けるでしょうか。
# *.hoge というファイルが存在しないので、Bash は '*.hoge' というファイル名をそのままコマンドに渡す $ ls *.hoge ls: cannot access '*.hoge': No such file or directory
この挙動がどういうときに困るかというと…
#!/bin/bash for f in *.hoge; do echo "file name is $f" done
上記のようなスクリプトを走らせると、*.hoge
に合致するファイルが存在しなかった結果、*.hoge
というリテラルがそのまま echo
に渡ってしまい、出力は file name is *.hoge
になってしまいます。
*.hoge
に合致するファイルが無いんであれば、単純にこの for ループは空回りして欲しいですよね。
そういうとき、shopt -s nullglob
で nullglob オプションを有効化します。
#!/bin/bash shopt -s nullglob for f in *.hoge; do echo $f done
nullglob は、「Glob に合致するファイル/ディレクトリが存在しない場合、Glob を空文字列に展開する」というオプションです。 この結果、上記の nullglob を有効化した for ループは空回りし、何も出力せずに終了させることができるようになります。
また、ls *.hoge
を実行するしようとすると、*.hoge
が空文字に展開されますので、ls
が実行されることになります。
failglob
failglob は、指定した Glob を展開しようとしたときに合致するファイル/ディレクトリが存在しない場合、エラーとしてコマンド実行も実施しないというオプションです。 インタラクティブに bash を使う場合、typo とかにすぐ気付くことができます。
# failglob が無効になっている場合 $ ls *.hoge ls: cannot access '*.hoge': No such file or directory # failglob を有効化した場合、ls は実行されないことが分かる $ shopt -s failglob $ ls *.hoge bash: no match: *.hoge
dotglob
Glob は、いわゆる隠しファイル (先頭が .
から始まるファイル) には合致しないのがデフォルトの動作です。
実はこの挙動、dotglob オプションで変更することができます。
# こうやって隠しファイルを作っても、デフォルトの設定だと Glob に合致しない $ touch .hiddenfile $ ls * test.txt # dotglob を有効化すると合致するようになる $ shopt -s dotglob $ ls * .hiddenfile test.txt
隠しファイルを含めて処理をしたい時とかに使うと処理が楽になります。
shopt -s dotglob for f in *; do echo $f # 隠しファイルも含める done