*sh shell 中的反引號(即 cmd
)是否已被棄用?
對於諸如 Bash 和 Zsh 之類的 shell,我在 Unix 和 Linux 以及其他使用“反引號已被棄用”的網站上多次看到此評論。
這個說法是真的還是假的?
“已棄用”有兩種不同的含義。
**不推薦使用:(**主要是軟體功能)可用但被視為已過時且最好避免,通常是由於已被取代。
——新牛津美國詞典
根據這個定義,反引號被棄用了。
棄用狀態也可能表明該功能將在未來被刪除。
—維基百科
根據這個定義,不推薦使用反引號。
仍然支持:
引用 Open Group Specification on Shell Command Languages,特別是第2.6.3 節命令替換,可以看出,就規範而言,仍然支持兩種形式的命令替換,反引號(
..cmd..
)或美元括號( )。$(..cmd..)
命令替換允許替換命令的輸出來代替命令名稱本身。當命令包含以下內容時,應進行命令替換:
$(command)
或(反引號版本):
`command`
shell 應通過在子 shell 環境中執行命令來擴展命令替換(請參閱 Shell 執行環境)並用命令的標準輸出替換命令替換(命令文本加上封閉
$()
或反引號),刪除一個或多個序列<newline> 字元在替換的末尾。輸出結束前嵌入的 <newline> 字元不應被刪除;但是,它們可能被視為欄位分隔符並在欄位拆分期間被消除,具體取決於 IFS 的值和有效的引用。如果輸出包含任何空字節,則行為未指定。在命令替換的反引號樣式中,<backslash>應保留其字面含義,除非後跟:’$’、’ ```’ 或<backslash>。對匹配反引號的搜尋應由第一個未引用的非轉義反引號來滿足;在此搜尋期間,如果在 shell 註釋、here-document、表單的嵌入式命令替換或帶引號的字元串中遇到非轉義的反引號
$(command)
,則會出現未定義的結果。在 " " 序列內開始但不結束的單引號或雙引號字元串...
會產生未定義的結果。使用該
$(command)
形式,從左括號到匹配的右括號的所有字元構成命令。任何有效的 shell 腳本都可用於命令,但僅由重定向組成的腳本除外,它會產生未指定的結果。那麼為什麼每個人都說反引號已被棄用?
因為大多數案例應該使用美元括號形式而不是反引號。(在上面的第一個意義上已棄用。)許多最有名的網站(包括 U&L)也經常聲明這一點,自始至終,所以這是合理的建議。不應將此建議與一些不存在的從 shell 中刪除對反引號的支持的計劃相混淆。
...
是只有最古老的不兼容 POSIX 的 bourne-shell 才需要的遺留語法。有幾個原因總是更喜歡這種$(...)
語法:…
這是較舊的 Bourne 兼容形式的命令替換。
COMMANDS
和語法都由$(COMMANDS)
POSIX 指定,但後者更受歡迎,儘管不幸的是前者在腳本中仍然非常普遍*。*每個現代 shell(以及一些)都廣泛實現了新型命令替換。使用反引號的唯一原因是為了與真正的 Bourne shell(如 Heirloom)兼容。反引號命令替換在嵌套時需要特殊的轉義,並且在野外發現的範例經常被不正確地引用。請參閱: 為什麼 $(…) 優於...
(反引號)?.由於這些不一致的行為,對於嵌套命令替換或嘗試嵌入複雜腳本的新應用程序,不建議使用反引號的命令替換。
**注意:**這第三段摘錄(上面)繼續顯示了反引號根本不起作用的幾種情況,但更新的美元括號方法可以,從以下段落開始:
此外,反引號語法對嵌入命令的內容有歷史限制。雖然較新的“$()”表單可以處理任何類型的有效嵌入腳本,但反引號表單不能處理一些包含反引號的有效腳本。
如果您繼續閱讀該部分,則會突出顯示失敗,顯示它們如何使用反引號失敗,但使用較新的美元括號表示法確實有效。
結論
因此,最好使用美元括號而不是反引號,但實際上您並沒有使用技術上“棄用”的東西,例如“這將在某個計劃點完全停止工作”。
閱讀完所有這些後,您應該明白強烈建議您使用美元括號,除非您特別需要與真正的原始非 POSIX Bourne shell 兼容。