2016-10-03 72 views
1

我有一個函數read_command定義爲:在函數擊變量替換

function read_command { 
    local __newline __lines __input __newstr __tmp i; 
    exec 3< "$*"; 
    __newline=$'\n'; 
    __lines=(); 
    while IFS= read <&3 -r __line && [ "$__line" != '####' ]; do 
     echo "$__line"; 
     __lines+=("$__line"); 
    done 
    while IFS= read <&3 -r __line && [ "$__line" != '####' ]; do 
     read -e -p "${__line#*:}$PS2" __input; 
     local ${__line%%:*}="$__input"; 
    done 
    __command=""; 
    for i in "${__lines[@]}"; do 
     __tmp=$(echo "${i}"); 
     __command="${__command} ${__newline} ${__tmp}"; 
    done 
    echo -e "$__command"; 
} 

在當前目錄中有一個名爲「測試」文件,用下面的 內容:

greet ${a:-"Bob"} 
greet ${b:-"Jim"} 
#### 
a: name of friend a 
b: name of friend b 
#### 

在終端中,執行的命令是

read_command test 

沒有輸入,我期待輸出最後陳述的認沽是:

greet Bob 
greet Jim 

但我得到的是:

greet ${a:-"Bob"} 
greet ${b:-"Jim"} 

這裏有什麼問題?

編輯:根據David的建議,在除了下面的一些情況下添加eval作品。

j=1;i="export DISPLAY=:0 && Xephyr :${j}&";k=$(eval echo "$i"); 
echo $k 

出口DISPLAY =:0

我期待k設定 「出口DISPLAY =:0 & & Xephyr:1 &」,這裏有什麼錯? 編輯:我試着用以下

k=$(eval "echo \"$i\"") 

這是鏈接到我工作的腳本。 https://gist.github.com/QiangF/565102ba3b6123942b9bf6b897c05f87

+0

行結束處的分號是多餘的;在shell腳本中,作爲命令分隔符,新行或分號就足夠了。 – tripleee

+0

我只是一個例子,網絡上有太多不好的例子。 – godblessfq

回答

2

在第一while循環,在echo "$__line",你有__line='greet ${a:-"Bob"}'。當您嘗試打印時,Bash不會將${a:-"Bob"}擴展爲Bob。 (即使您刪除$__line左右的引號,也不會發生這種情況。)要獲得該效果,您需要添加eval,例如eval echo "$__line"。不幸的是eval帶有它的蠕蟲,你必須開始擔心報價水平等之間的相互作用。

+0

如何防止「eval echo $ __ line」在__line中執行命令,請參閱問題中的編輯。 – godblessfq

+0

這看起來非常像[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。這個代碼實際上試圖解決什麼問題?這也看似隱約像http://mywiki.wooledge.org/BashFAQ/050 – tripleee

+0

cheat.sh的替代方案是使用模板替換,但它不太方便。 (https://github.com/tests-always-included/mo) – godblessfq