如何將使用萬用字元建構並包含空格的路徑儲存到變數中
情況如下(我使用的是 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_DIR
像tar
這樣使用:$ 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
,然後命令還有兩個參數tar
:Illustrator*/Cool
和Extras.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"