一致するものがない場合、*がそれ自体で返される理由は理解できません。これ回答これが実際に本当だと指摘していますが、私はこの行動の根拠を理解していません。一致しない場合*または他の一般的なパターンが空の文字列を返さないのはなぜですか?
$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の最初のバージョンで見ることができます。
全体的な状況エラーが印刷され、ここに渡されたコマンドは実行されません。
エラーメッセージは次のとおりです。「不一致」。
現代のシェルからボン(Unixバージョン7)ls -l *.c
、「*.c:対応するファイルまたはディレクトリがありません」というエラーが生成されます。このメッセージがわかりやすいと言いたいです。また、失敗パターンを示します。
*.c
拡張子が空の場合、ls -l *.c
ディレクトリ内のすべてのファイルが表示され、エラーは印刷されません。
failglob
bashには元の動作に近いオプションがあります。
答え2
*実際にはbash(シェルは何でも)によって拡張され、次に渡されます。エコ。これエコこのコマンドは何も実行せず、標準出力に出力します。この記事を読む -ファイル名拡張子。それは言う -
Bash は、各単語から「*」、「?」、「[」の文字を検索します。これらの文字のいずれかが発生すると、その単語はパターンとして扱われ、パターンと一致するファイル名のアルファベット順のリストに置き換えられます。一致するファイル名がなく、シェルオプションnullglobが無効になっている場合、単語は変更されずに残ります。 nullglob オプションが設定されていて一致するものがない場合、その単語は削除されます。
したがって、実際にbashが一致するものを見つけることができない場合は、「*」を変更せずにそのままにしてechoとして印刷します。
理由
bashがデフォルトで空のステートメントを返さないのは、ユーザーがワイルドカードとして「*」を使用しないため、「*」拡張を必要としないためです。したがって、この場合、「*」を空の文字列に拡張するとエラーになります。ただし、このデフォルトの動作はoptionsで上書きできますnullglob
。