Bash

在 Bash 中引用 $(命令替換)

  • April 27, 2021

在我的 Bash 環境中,我使用包含空格的變數,並在命令替換中使用這些變數。

引用我的變數的正確方法是什麼?如果這些是嵌套的,我該怎麼做?

DIRNAME=$(dirname "$FILE")

還是我在替換之外引用?

DIRNAME="$(dirname $FILE)"

或兩者?

DIRNAME="$(dirname "$FILE")"

還是我使用反引號?

DIRNAME=`dirname "$FILE"`

這樣做的正確方法是什麼?以及如何輕鬆檢查報價是否設置正確?

從最差到最好的順序:

  • DIRNAME="$(dirname $FILE)" 如果$FILE包含空格(或$IFS目前包含的任何字元)或萬用字元,則不會執行您想要\[?*的操作。
  • DIRNAME=dirname “$FILE”``在技​​術上是正確的,但不建議將反引號用於命令擴展,因為嵌套它們時會增加額外的複雜性,並且會在其中發生額外的反斜杠處理。
  • DIRNAME=$(dirname "$FILE")是正確的,但僅僅是因為這是對標量(不是數組)變數的賦值。如果您在任何其他上下文中使用命令替換,例如export DIRNAME=$(dirname "$FILE")or du $(dirname -- "$FILE"),如果擴展結果包含空格或萬用字元,則缺少引號將導致麻煩。
  • DIRNAME="$(dirname "$FILE")"(除了缺少的--,見下文)是推薦的方式。您可以DIRNAME=用命令和空格替換而不更改任何其他內容,並dirname接收正確的字元串。

為了進一步改進:

  • DIRNAME="$(dirname -- "$FILE")"如果$FILE以破折號開頭,則有效。
  • DIRNAME="$(dirname -- "$FILE" && printf x)" && DIRNAME="${DIRNAME%?x}" || exit即使$FILE’s dirname 以換行符結尾也可以工作,因為$()在輸出末尾切斷換行符,包括添加的換行符dirname和可能是實際數據一部分的換行符。

您可以隨意嵌套命令擴展。始終創建一個新的引用上下文,因此$()您可以執行以下操作:

foo "$(bar "$(baz "$(ban "bla")")")"

不想用反引號來嘗試。

引用自:https://unix.stackexchange.com/questions/118433