我正在编写一个shell脚本,在运行之前需要检查系统Perl更新是否已经破坏了粘贴在一起的Perl脚本.我不断得到解析错误.要在命令行上重现此信息:
$ module='Scalar::Util'; check="perl -e 'use $module' 2>&1"; check_status=`$check`; echo $check
Can't find string terminator "'" anywhere before EOF at -e line 1.
perl -e 'use Scalar::Util' 2>&1
Run Code Online (Sandbox Code Playgroud)
有谁看到我做错了什么?
谢谢.
像这样处理带有空格的参数充其量是棘手的; 尽量避免这样做.
你还应该使用更多的垂直空间; 'one-liners'是一个贬义词,而不是一个批准词.
你有:
module='Scalar::Util'
check="perl -e 'use $module' 2>&1"
check_status=`$check`
echo $check
Run Code Online (Sandbox Code Playgroud)
麻烦的是当shell处理时:
`$check`
Run Code Online (Sandbox Code Playgroud)
它在字边界处拆分字符串,产生参数:
perl
-e
'use
Scalar::Util'
2>&1
Run Code Online (Sandbox Code Playgroud)
请注意,I/O重定向被视为参数!为避免此问题,在此上下文中,您可以使用:
module='Scalar::Util'
check="perl -e 'use $module' 2>&1"
check_status=`eval $check`
echo $check
Run Code Online (Sandbox Code Playgroud)
该eval部队的外壳重新分析了线,没有得到任何错误.
小心; 简单地使用eval并不总是这些困境的解决方案.特别是,如果你有反斜杠,美元或反引号(或更多的引号),那么eval可以简单地解决问题.
检查Perl中是否存在模块的一种方法是:
perl -M$module -e "print $module::VERSION . '\n'"
Run Code Online (Sandbox Code Playgroud)
这给出了模块的版本号(并使字符串复杂化).你也可以简单地做:
perl -M$module -e exit
Run Code Online (Sandbox Code Playgroud)
如果模块已加载,它将以状态0退出,如果不是,则退出错误等.
$ perl -MSalar::Util -e exit
Can't locate Salar/Util.pm in @INC (@INC contains: /Users/jleffler/Perl/v5.14.1-64/lib/perl5/site_perl/5.14.1/darwin-2level /Users/jleffler/Perl/v5.14.1-64/lib/perl5/site_perl/5.14.1 /Users/jleffler/Perl/v5.14.1-64/lib/perl5/5.14.1/darwin-2level /Users/jleffler/Perl/v5.14.1-64/lib/perl5/5.14.1 .).
BEGIN failed--compilation aborted.
$ echo $?
2
$
Run Code Online (Sandbox Code Playgroud)