はじめに
Bash で該当ディレクトリ内にあるファイルを一括でコマンドの引数として渡したい場合は、 * を使った Glob 機能が便利です。
さて、この * を使ったワイルドカードによるコマンドライン引数の展開ですが、「パターンにマッチするファイルが無かった場合」に想定しない挙動をしてしまうことがあります。
「パターンにマッチするファイルが無かった場合」にどんな問題が起きるか と その対処法 を紹介します。
検証環境
| |
作業の流れ(作業ログ)
Glob によるパラーんマッチの挙動を確認するために、 事前にカレントディレクトリに数ファイル作成しておきます。
名前は単純に以下のような数字の連番としておきます。
10.txt11.txt12.txt
| |
Glob によるパターンマッチを試してみる
それでは Bash Glob によるパターンマッチの機能を使ってみます。
Glob 機能ではパターンにマッチした部分がコマンドライン引数として展開されます。 ( 厳密には引数以外の部分にも適用されますが、引数として利用するケースがほとんどのはずです。 )
パターンが 1 ファイル以上にマッチした場合
まずはファイル名が .txt で終わるファイルを検出し、コマンドライン引数として展開された場合の挙動をみてみましょう。
これは echo 10.txt 11.txt 12.txt を実行した結果と同様になります。
| |
次に、ファイル名が 1.txt で終わるファイルを検出し、コマンドライン引数として展開された場合の挙動をみてみましょう。
これは echo 11.txt を実行した結果と同様になります。
| |
ここまではなんの問題もありませんね。
パターンがどのファイルにもマッチしなかった場合
今度はパターンの結果がどのファイルにもマッチしなかった場合の挙動を見ていきます。
ファイル名が 3.txt で終わるファイルを検出し、コマンドライン引数として展開してみます。
| |
ファイルが検出されたなかった場合ですが、展開前の文字列がそのままコマンドライン引数として渡ってしまいます。
これを意図した挙動として取り扱う場合は少ないと思います。
set -o nullglob オプションを使用する
*3.txt のようなどのファイルにもマッチしないようなパターンが指定されたときには何も表示されないようにしたい場合は、
set -o nullglob という Bash の設定を行います。
| |
このように、
- パターンマッチしたファイルが見つかった場合の挙動はかわりなし
- パターンマッチしたファイルがない場合には引数が空となる
ことがわかります。
ひとこと
というような問題があったり、 フォルダがサブディレクトリに格納されているケースも考えないといけないことがあったりします。
ですので僕は find をファイル名にスペースを含んでいても正しく処理できるようなオプション付きで実行することがほとんどです。
やり方は過去のエントリで取り上げています。