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則會顯示目錄中的所有文件,並且不會列印錯誤。

bash 有一個failglob更接近原始行為的選項。

答案2

* 實際上是由 bash (無論你的 shell 是什麼)擴展的,然後它被傳遞到迴音。這迴音命令不執行任何操作,只是將其列印到標準輸出。閱讀本文檔 -檔案名稱擴充。它說-

Bash 掃描每個單字中的字元「*」、「?」和「[」。如果出現這些字元之一,則該單字被視為模式,並替換為與該模式相符的按字母順序排序的檔案名稱清單。如果沒有找到符合的檔案名,並且 shell 選項 nullglob 被停用,則該單字將保持不變。如果設定了 nullglob 選項,並且未找到匹配項,則該單字將被刪除。

所以實際上,當 bash 找不到任何匹配時,它會保留 '*' 不變,並 echo 打印出來。

原因 bash 預設不回傳空語句的原因是,在某些情況下,使用者不想使用「*」作為通配符,因此他不需要「*」的擴充。因此在這種情況下,將“*”擴展為空字串將是錯誤的。但是,可以透過選項覆寫此預設行為nullglob

相關內容