2016-10-03 67 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