我编写了一个简单的shell脚本来获取服务器上安装的Perl模块的版本,并且一直收到以下错误:
Can't find string terminator "'" anywhere before EOF at -e line 1.下面是我的脚本:
#!/bin/sh
#
mod_name="Sub::Uplevel"
tmp1="perl -M$mod_name -e 'print \"\$$mod_name::VERSION\"'"
echo $tmp1
$tmp1如果我直接运行echo'd行(perl -MSub::Uplevel -e 'print "$Sub::Uplevel::VERSION"'),它就可以工作。
发布于 2012-01-31 01:29:40
除了$tmp1之外,eval还可以工作:
eval "$tmp1"这是因为将变量拆分成单词(对于参数)是严格通过对$IFS进行拆分来完成的,而不是常规的输入解析。eval强制进行正常的输入解析。
我是怎么弄明白的?
更改您的tmp1=行,将echo放在前面,您将得到:
perl -MSub::Uplevel -e 'print "$Sub::Uplevel::VERSION"'请注意,'仍然在那里,这是您意想不到的。如果您编写了一个快速脚本:
#!/bin/sh
for a in "$@"; do
echo "arg: $a"
done然后调用它而不是echo,你会发现参数实际上是如何分裂的:
arg: perl
arg: -MSub::Uplevel
arg: -e
arg: 'print
arg: "$Sub::Uplevel::VERSION"'所以,你可以看到这是在空格上拆分,所以IFS。
发布于 2012-01-31 02:44:04
使用bash数组构造命令总是更好。这将使带有空格的参数正确分组:
#!/bin/bash
mod_name="Sub::Uplevel"
perl_script=$(printf 'print "$%s::VERSION"' $mod_name)
tmp1=(perl -M$mod_name -e "$perl_script")
echo "${tmp1[@]}"
output=$( "${tmp1[@]}" )数组是一个bash特性,因此shebang行必须引用bash而不是sh。
发布于 2012-01-31 01:38:01
我通常会写下你用反引号做的事情,在shell中运行命令:
#!/bin/sh
#
mod_name="Sub::Uplevel"
tmp1=`perl -M$mod_name -e 'print \"\$$mod_name::VERSION\"'`
echo $tmp1然后,您可以根据需要在$tmp1上工作。它还避免了处理转义。
https://stackoverflow.com/questions/9067580
复制相似问题