[英]bash quotes in variable treated different when expanded to command
通過例子解釋問題......
證明 - 變量擴展后,--chapters之后的單引號會被轉義(我沒想到):
prompt@ubuntu:/my/scripts$ cat test1.sh
#!/bin/bash
actions="--tags all:"
actions+=" --chapters ''"
mkvpropedit "$1" $actions
prompt@ubuntu:/my/scripts$ ./test1.sh some.mkv
Error: Could not open '''' for reading.
現在由於某種原因,mkvpropedit接收雙引號作為文件名的一部分(我也沒想到):
prompt@ubuntu:/my/scripts$ cat test1x.sh
#!/bin/bash
command="mkvpropedit \"$1\""
command+=" --tags all:"
command+=" --chapters ''"
echo "$command"
$command
prompt@ubuntu:/my/scripts$ ./test1x.sh some.mkv
mkvpropedit "some.mkv" --tags all: --chapters ''
Error: Could not open '''' for reading.
上面的echo'd命令似乎是正確的。 將相同的文本放在另一個腳本中會得到預期的結果:
prompt@ubuntu:/my/scripts$ cat test2.sh
#!/bin/bash
mkvpropedit "$1" --tags all: --chapters ''
prompt@ubuntu:/my/scripts$ ./test2.sh some.mkv
The file is being analyzed.
The changes are written to the file.
Done.
任何人都可以解釋為什么報價不符合預期。 我發現在這個問題上搜索很困難,因為網上有很多其他的引用討論。 我甚至不知道如何在沒有例子的情況下解釋這個問題。
我擔心有一天,參數中的文件名包含一些破壞一切的字符,因此可能過多引用。 我不明白為什么直接在腳本中輸入或通過變量提供時相同的命令執行方式不同。 請賜教。
謝謝閱讀。
需要記住的重要一點是,在最初解析命令行時, 引號只會被刪除一次 。 由於參數替換( $foo
)或命令替換( $(cmd args)
)而插入命令行的引用不被視為特殊字符。 [注1]
這似乎與空格和glob元字符不同。 在參數/命令替換之后發生字拆分和路徑名擴展(除非替換發生在引號內)。 [筆記2]
結果是,創建一個bash變量$args
幾乎是不可能的
cmd $args
如果$args
包含引號,則不會刪除它們。 $args
中的單詞由空格序列分隔,而不是單個空白字符。
唯一的方法是將$IFS
設置$IFS
包含一些非空白字符; 然后,該字符可以在$args
作為單字符分隔符使用。 但是, 沒有辦法在值中引用字符 ,因此一旦這樣做,您選擇的字符除了作為分隔符之外不能使用。 這通常不太令人滿意。
但是有一個解決方案:bash數組。
如果將$args
轉換為數組變量,則可以使用重復引用語法對其進行擴展:
cmd "${args[@]}"
它為$args
每個元素生成一個單詞,並禁止在這些單詞上進行單詞拆分和路徑名擴展,因此它們最終成為文字。
所以,例如:
actions=(--tags all:)
actions+=(--chapters '')
mkvpropedit "$1" "${actions[@]}"
可能會做你想要的。 那會:
args=("$1")
args+=(--tags)
args+=(all:)
args+=(--chapters)
args+=('')
mkvpropedit "${args[@]}"
等等
command=(mkvpropedit "$1" --tags all: --chapters '')
"${command[@]}"
我希望這是半透明的。
man bash
(或在線版本 )包含一個關於bash匯編命令的詳細說明,從“EXPANSION”部分開始。 值得閱讀以獲得完整的解釋。
筆記:
這不適用於eval
或bash -c
類的命令,它們在命令行處理后再次評估它們的參數。 但那是因為命令行處理發生了兩次。
單詞拆分與“將命令划分為單詞”不同,這在解析命令時會發生。 首先,單詞拆分使用$IFS
的值作為分隔符,而命令行解析使用空格。 但這些都不是在引號內完成的,所以它們在這方面是相似的。 在任何情況下,在參數替換之前和之后,單詞都以這種或那種方式分開。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.