2015-08-28 11 views
0

如果我救下面的腳本爲「args.bash」和運行bash args.bash -a 'foo bar'

#!/bin/bash 

main() { 
    set -x 
    which "[email protected]" 

    local args="[email protected]" 
    which "$args" 
    which $args 

    local args=$(printf " %q" "[email protected]") 
    which "$args" 
    which $args 
} 
main "[email protected]" 

我很驚訝地看到,這些打印不同的結果。第一個打印:

which -a 'foo bar' 

我期望!它將正確的參數分組。

他們其餘的打印,依次是:

which '-a foo bar' 
which -a foo bar 
which ' -a foo\ bar' 
which -a 'foo\' bar 

這都是不正確的或多或少。我如何將"[email protected]"分配給一個變量,並讓它回顯與第一個命令相同的輸出?

+2

你不能在字符串中存儲任意的命令/參數,並保持正確的引號/等。參見[Bash FAQ 050](http://mywiki.wooledge.org/BashFAQ/050)討論這個問題。你需要使用一個數組。 –

+0

好吧 - 他正在使用'printf%q',它改變了一些東西,但是一個數組仍然是正確的。 –

+0

'printf%q'是我知道的唯一嘗試 - 打開任何其他建議。 –

回答

4

使用數組變量,而不是一個標量:

items=("[email protected]") 
which -a "${items[@]}" 

但是,如果必須使用標 [1],你有沒有和printf '%q '正確的方法;但是請注意,這printf %q創建時通過充分解析器運行(因此需要eval或等效,以確保充分的解析器調用),這將評估回本身字符串:

printf -v items_str '%q ' "[email protected]" 
eval "which -a $items_str" 

[1]其中一個具有bash擴展名(如printf -v%q但不能使用數組)的情況數量有限,但它們確實存在;特別是通過環境將價值傳遞給子過程時,我想到了這一點。然而,在數組不合適的情況下,我希望使用一系列不同的環境變量(每個值一個),或者傳遞NUL分隔的流(由printf '%s\n' "[email protected]"創建)更合適,即使(至於環境),它可能需要轉義(例如,通過base64編碼)。

+0

呃,所以你必須在那裏使用eval? –

+0

如果你不想做正確的事情並使用數組,是的。 –

+0

很酷,謝謝!超級整潔! –