Bash

如何將使用萬用字元建構並包含空格的路徑儲存到變數中

  • February 15, 2016

情況如下(我使用的是 Mac,OS X El Capitan):

# This works:

$ cd /Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates/;

# These do not work:

$ INSTALL_DIR=/Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates;
$ cd $INSTALL_DIR
# Moves me here: /Applications/Adobe

$ cd "$INSTALL_DIR"
-bash: cd: /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates: No such file or directory

$ cd "${INSTALL_DIR}"
-bash: cd: /Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates: No such file or directory

我的目標是$INSTALL_DIRtar這樣使用:

$ tar -xz $SOURCE_ZIP --strip-components 1 -C $INSTALL_DIR "*.ait";

不幸的是,-C(更改為目標目錄)不喜歡 ; 中的空格$INSTALL_DIR。如果我使用引號,我將無法*正常工作。

有沒有一種優雅的方式來處理這種情況?

當 * 沒有被引用時,shell 在執行命令之前擴展參數列表。它將擴展參數列表傳遞給程序。

當 * 出現在帶引號的字元串中時,它在傳遞給程序之前不會被 shell 擴展。

嘗試擴展路徑,將其分配給另一個變數,然後在將第二個變數作為參數傳遞時引用它。

問題不在於 tar,而在於您的 shell 程式碼。該-C選項的參數應該是路徑,而不是萬用字元模式。cd請注意,您在命令中遇到了完全相同的問題。

INSTALL_DIR您在變數中儲存了萬用字元模式。當您編寫 時-C $INSTALL_DIR,這將應用“split+glob”運算符:獲取變數的值,將其拆分為空格,並將每個單詞解釋為萬用字元模式,然後將其展開。這裡變數的值為/Applications/Adobe Illustrator*/Cool Extras.localized/en_US/Templates,分為三個字/Applications/Adobe, Illustrator*/Cool, Extras.localized/en_US/Templates; 中間的單詞包含一個萬用字元 ( *),因此它被解釋為一個萬用字元模式,但由於它不匹配任何文件,所以該模式保持原樣。這使-C選項的參數成為字元串/Applications/Adobe,然後命令還有兩個參數tarIllustrator*/CoolExtras.localized/en_US/Templates

如果使用雙引號,那麼"$INSTALL_DIR"就是變數的值INSTALL_DIR。仍然在*其中,因為它從未在任何時候擴展過。

根據經驗,萬用字元會在需要多個單詞的上下文中擴展。畢竟,一般來說,萬用字元模式匹配多個文件。賦值的右側禁止萬用字元擴展,因為結果應該是單個字元串。要獲取列表,請分配給數組變數而不是字元串變數:

INSTALL_DIRS=(/Applications/Adobe\ Illustrator*/Cool\ Extras.localized/en_US/Templates)

如果您安裝了多個版本的 Illustrator,則可能存在多個數組元素。讓我們來看看最後一個元素。

INSTALL_DIR=${INSTALL_DIRS[$((${#INSTALL_DIRS}-1))]}

現在INSTALL_DIR是現有文件的路徑(假設萬用字元匹配)。您可以正常使用它(即您可以在雙引號內展開它)。

tar -xz "$SOURCE_ZIP" --strip-components 1 -C "$INSTALL_DIR" "*.ait"

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