首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么只有当命令在变量中时,才会出现“无法找到字符串终止符”的错误?

为什么只有当命令在变量中时,才会出现“无法找到字符串终止符”的错误?
EN

Stack Overflow用户
提问于 2012-01-31 00:55:57
回答 4查看 1.4K关注 0票数 3

我编写了一个简单的shell脚本来获取服务器上安装的Perl模块的版本,并且一直收到以下错误:

代码语言:javascript
复制
Can't find string terminator "'" anywhere before EOF at -e line 1.

下面是我的脚本:

代码语言:javascript
复制
#!/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"'),它就可以工作。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-01-31 01:29:40

除了$tmp1之外,eval还可以工作:

代码语言:javascript
复制
eval "$tmp1"

这是因为将变量拆分成单词(对于参数)是严格通过对$IFS进行拆分来完成的,而不是常规的输入解析。eval强制进行正常的输入解析。

我是怎么弄明白的?

更改您的tmp1=行,将echo放在前面,您将得到:

代码语言:javascript
复制
perl -MSub::Uplevel -e 'print "$Sub::Uplevel::VERSION"'

请注意,'仍然在那里,这是您意想不到的。如果您编写了一个快速脚本:

代码语言:javascript
复制
#!/bin/sh

for a in "$@"; do
    echo "arg: $a"
done

然后调用它而不是echo,你会发现参数实际上是如何分裂的:

代码语言:javascript
复制
arg: perl
arg: -MSub::Uplevel
arg: -e
arg: 'print
arg: "$Sub::Uplevel::VERSION"'

所以,你可以看到这是在空格上拆分,所以IFS。

票数 3
EN

Stack Overflow用户

发布于 2012-01-31 02:44:04

使用bash数组构造命令总是更好。这将使带有空格的参数正确分组:

代码语言:javascript
复制
#!/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

票数 2
EN

Stack Overflow用户

发布于 2012-01-31 01:38:01

我通常会写下你用反引号做的事情,在shell中运行命令:

代码语言:javascript
复制
#!/bin/sh
#
mod_name="Sub::Uplevel"
tmp1=`perl -M$mod_name -e 'print \"\$$mod_name::VERSION\"'`
echo $tmp1

然后,您可以根据需要在$tmp1上工作。它还避免了处理转义。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9067580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档