2014-02-26 28 views
2

我有project written in bash。該接口的一個部分需要用戶調用的bash功能與間接層,像這樣:

require some_fun "arg 1" "arg 2" 

其執行some_fun "arg 1" "arg 2"(然後執行一些額外的事情,因此,它存在的原因)。目前我只是調用"[email protected]"來做到這一點,一切正常。

我現在有需要推遲這些函數調用,直到後來,並找不到在Bash中這樣做的方法。實際上,我希望每次調用require時將"[email protected]"壓入堆棧,然後遍歷該堆棧並執行參數,就像我當前的行爲一樣。這需要多維數組,其中的bash不支持,所以我想這樣的:

require() { 
    dep_num=${#SK_deps[@]} 
    dep_var="SK_dep_$dep_num" 
    eval $dep_var="[email protected]" 
    SK_deps+=($dep_var) 
} 

這基本上產生可變變量來存儲「$ @」,並把變量名$SK_deps

然後我嘗試遍歷與列表:

for dep_var in ${SK_deps[@]} 
do 
    ${!dep_name} 
done 

但是,這似乎打破了報價參數,所以:

require some_fun "arg 1" "arg 2" 

被解釋爲:

require some_fun arg 1 arg 2 

沒有引號。

有沒有辦法做我想做的事情?使用「$ *」也會導致報價定位的丟失。感覺應該有一種方法可以在Bash中執行此操作,而不會使用sed/awk進行攻擊。

回答

5

eval解決方案並不是那麼糟糕。關鍵是要充分利用printf殼報價機制,這將處理所有棘手的情況下爲您提供:

require() { 
    local quoted 
    printf -v quoted ' %q' "[email protected]" 
    SK_deps+=("$quoted") 
} 

然後就可以正常運行:

for dep in "${SK_deps[@]}"; do eval $dep; done 
+0

太棒了。我不知道這存在。將盡快嘗試:) – d11wtq

+0

作品一種享受,謝謝! – d11wtq

1

報價擴展它當數組:

for dep_var in "${SK_deps[@]}" 
do 
    ${!dep_name} 
done 

而且下面一行顯得可疑:

eval $dep_var="[email protected]" 

嘗試用set -xv運行腳本,看看變量是如何真正擴大。

+0

'$ SK_deps'是隻是一組變量*名稱*,而不是參數本身。它只是填充了像'SK_dep_0'和'SK_dep_5'這樣的字符串;) – d11wtq

+0

我想我已經找出了一個解決方案(至少在我的腦海中)存儲'$#'和'$ 1,$ 2,... $ n'分別。 – d11wtq

+0

是的,我一直在輸出擴展,它肯定是缺少引號。我也嘗試'eval $ dep_var = \「$ @ \」',以便引用是在eval中,無濟於事。 – d11wtq

0

我發現了一個非常醜陋的解決方案,使用eval,所以任何更好的建議將不勝感激。

require() { 
    local tmp_var="" 
    for arg in "[email protected]" 
    do 
    tmp_var="$tmp_var \"$arg\"" 
    done 
    SK_deps+=("$tmp_var") 
} 

然後:

for dep in "${SK_deps[@]}" 
do 
    eval $dep 
done 

它使用這樣的eval充滿了邊緣的情況下,如已經在ARGS報價,或者已經在ARGS反斜線很清楚,等

相關問題