我遇到过单引号在系统调用中导致Bash'未终止的引用字符串'错误的情况。在这种特定情况下,我试图将$DBI::errstr
插入到bash命令中。我在系统调用中使用:
system "echo '$DBI::errstr' | mail -s 'error' usr@mail.com";
所以$DBI::errstr
有时包含单引号并导致错误。我知道我可以将$DBI::errstr
括在后面的双引号\"$DBI::errstr\"
中并将其称为一天,但必须有一个更好的方法来处理带有正则表达式或编写子例程的引号,我我很难找到。我也试过quotemeta
,但这也会反过来削减空间。
答案 0 :(得分:4)
没有充分的理由在Perl中使用system echo
。您只需打开一个管道作为文件句柄并打印到它:
open my $mail, '|-', qw/mail -s error usr@mail.com/ or die $!;
print $mail $DBI::errstr, "\n";
编辑:但要更一般地回答你的问题。而不是依靠shell来解析和取消引用命令行字符串并将其转换为参数,使用system()
的显式多参数形式通常更好。因此,代替system "some_command --arg=$val"
并担心是否需要为shell引用$val
,您可以使用system("some_command", "--arg=$val")
。
答案 1 :(得分:2)
如果你打算使用system
,这就是你要做的事情:
use String::ShellQuote qw( shell_quote );
my $cmd1 = shell_quote('echo', $DBI::errstr);
my $cmd2 = shell_quote('mail', '-s', 'error', $email_addr);
system("$cmd1 | $cmd2");