Bash: 一致しない場合に * が空の文字列を返さないのはなぜですか

Bash: 一致しない場合に * が空の文字列を返さないのはなぜですか

一致するものがないのに*が自分自身を返す理由がわかりません。答えはそうであると述べていますが、この動作の根拠がわかりません。一致しない場合は、* または任意の汎用パターンが空の文字列を返さないのはなぜですか?

$ls      # Look, no files
$touch a # Add a file
$echo *  # Works as expected
a
$rm a    # Remove the file
$echo *  # Will output a '*'. Why not ''?
*
$*       # Ok, * will fail, but how come the previous output?
-bash: *: command not found
$

答え1

どのファイルにも一致しないパターンはエラーとみなされます。これは、Unix の最初のバージョンで確認できます。

グロブエラーが出力され、渡されたコマンドは実行されません。

エラーメッセージは"勝ち目がない"

あなたの現代のシェルから派生したBourne (Unix バージョン 7)は、ls -l *.c「*.c: そのようなファイルまたはディレクトリはありません」というエラーを生成します。このメッセージの方が理解しやすいと思います。また、失敗したパターンも示します。

*.cが空に展開された場合、ls -l *.c代わりにディレクトリ内のすべてのファイルが表示され、エラーは出力されないことに注意してください。

bashfailglobには、元の動作に近いオプションがあります。

答え2

*は実際にはbash(シェルは何でも)によって展開され、その後に渡されます。エコーエコーコマンドは何もせず、標準出力に出力します。このドキュメントを読んでください -ファイル名の拡張。それはこう言っている。

Bash は各単語をスキャンして、文字「*」、「?」、および「[」を探します。これらの文字のいずれかが見つかった場合、その単語はパターンと見なされ、パターンに一致するファイル名のアルファベット順のリストに置き換えられます。一致するファイル名が見つからず、シェル オプション nullglob が無効になっている場合、単語は変更されません。nullglob オプションが設定されていて、一致するものが見つからない場合、単語は削除されます。

したがって、実際に bash が一致するものを見つけられない場合、 '*' は変更されずに、echo によってそれが出力されます。

理由 bash がデフォルトで空のステートメントを返さない理由は、ユーザーが '*' をワイルドカードとして使用したくないため '*' の展開が必要ない場合があるためです。したがって、この場合 '*' を空の文字列に展開するとエラーになります。ただし、このデフォルトの動作はnullglobオプションによって上書きできます。

関連情報