シェルワイルドカードとドットファイル

シェルワイルドカードとドットファイル

次の2つのコードが期待どおりに機能するのはなぜですか?

ls -d .[!.]?*
echo [D]*

しかし、次の2つはそうではありません。

ls -d [.][!.]?*
echo [D]

最初のコマンドでエラーが発生します。

ls: cannot access [.][!.]*: No such file or directory

同じリストを取得しようとするとls -d .[!.]?*。 2番目の出力は次のとおりです。

[D]

同様のエラーの説明を期待したときNo such file or directory。私は何を見逃していますか?上記の2番目の例のセットに示されているワイルドカード要素が式を削除しない場合、式をワイルドカードにするのは正確に何ですか?

言う(コメントにもあります):

ワイルドカードは を[D]*出力するだけでなく、…Dなども出力します。ところでDというファイルがある時もあっていない時も試してみました。ファイルが存在する場合、出力は機能しますが、ファイルが存在しない場合でも出力を取得します。理由がわからない。ディレクトリにファイルがある場合、式[D]がワイルドカードから非ワイルドカードに変更されるのはなぜですか?DesktopDownloadsecho [D]D[D]

答え1

デフォルトでは、bash(シェル)は、ドットが明示的に指定されていない限り、ドット(隠しファイルと見なされる)で始まるファイル名を拡張しません。[.]これはリテラル文字ではなくパターンなので、隠されたファイルの表示をトリガーしないため、ls -d [.][!.]?*どんなものとも一致しません。

shopt -s dotglobファイル名パターンを拡張するとき(「globbing」と呼ばれる)、常に隠しファイルを含めるようにオプションを設定することで、このデフォルトの動作を変更できます。

はい(行の先頭のドル記号はシェルプロンプトを表します。入力しないでください):

$ touch .foo
$ ls -d .[!.]?*
.foo
$ ls -d [.][!.]?*
ls: cannot access [.][!.]?*: No such file or directory
$ shopt -s dotglob
$ ls -d [.][!.]?*
.foo

問題は、echo [D]ファイル名が一致しないと拡張が行われないことです。D試してもファイルを指定しなかったため、echo実際に入力した内容が提供され、エコーされます。

ファイル名が一致する場合にのみパス名拡張が発生する例:

$ touch apple
$ echo a*
apple
$ rm apple
$ echo a*
a*

一致するファイルをすべて削除した[D]*場合。echo [D]*[D]*

関連情報