系统(“echo-e$str”)不能在perl中正确输出
我编写了这样一个简单的perl脚本系统(“echo-e$str”)不能在perl中正确输出,perl,echo,system,Perl,Echo,System,我编写了这样一个简单的perl脚本 #!/usr/bin/perl my $str = "hello\nworld"; my $cmd = "echo -e $str"; system($cmd); 输出为: -e hello sh: 2: world: not found 这是预料不到的。我想要的是: hello world 注意,“echo-e”可以正常工作,因为当我运行以下命令时 echo -e "hello\nworld" 输出是正确的 有什么解决办法吗 my $cmd = qq
#!/usr/bin/perl
my $str = "hello\nworld";
my $cmd = "echo -e $str";
system($cmd);
输出为:
-e hello
sh: 2: world: not found
这是预料不到的。我想要的是:
hello
world
注意,“echo-e”可以正常工作,因为当我运行以下命令时
echo -e "hello\nworld"
输出是正确的
有什么解决办法吗
my $cmd = qq(echo -e "$str");
系统参数字符串中的新行类似于代码>。它分离命令。为了避免这种情况发生,你需要把它放在引号里
系统参数字符串中的新行类似于代码>。它分离命令。为了避免这种情况发生,您需要将其放在引号内。如果设置后打印出$cmd
,您将看到:
echo -e hello
world
。。。如果您将其粘贴到shell中,您将得到类似的错误消息,尽管没有-e
第一个问题是,当它到达shell时,字符串同时缺少引号和非文字换行符。试试这个:
my $str = "hello\\nworld";
my $cmd = "echo -e '$str'";
在这种特殊情况下,您可以只使用引号,因为echo
的参数中会有一个文字换行符,但只要它被引用,这是合法的
但是,您仍然会在输出中获得文本-e
,并且不会将\n
解释为换行符。这是因为perl运行的是/bin/echo
,而不是bash中内置的echo
。如果您想使用bash的内置代码,就必须明确地告诉perl运行bash
。但这意味着将echo命令本身在参数中传递给bash,这将引入另一个级别的引用来处理
这里(实际上,在任何地方)最好的选择是使用多参数版本的系统
;它绕过第一个shell级别并直接执行命令。我们仍然需要处理新线:
my $str = "hello\nworld"; # literal newline
(my $escaped_str = $str) =~ s,\n,\\n,g; # escaped newline
为了从shell中获得所需的行为,我们需要将字符串嵌入shell命令中的单引号中,因为单引号中的任何内容都完全由shell执行。在本例中,我们只是从Perl代码中的一个文本中分配了字符串,因此我们确切地知道它包含什么,并且它不包含撇号。但如果它可能包含撇号,我们应该通过另一个转义过程来引用它们,这样就可以安全地嵌入单引号:
$escaped_str =~ s,','\\'',g; # quote any embedded apostrophes
您可能还希望用转义符替换其他字符—可能是制表符或回车符。这也将是做出这些改变的地方
使用转义字符串生成bash命令:
my $command = "echo -ne '$escaped_str'"; # bash command to echo string
像这样进行手动搜索/替换容易出错;有很多边缘情况需要考虑。因此,您可能还想看看CPAN模块,在该模块中,您可以跳过上面的手动转义,并从原始字符串生成转义字符串,如下所示:
my $command = shell_quote("echo", "-ne", $str);
获得转义命令字符串后,使用多参数system
将该字符串作为参数直接运行bash:
system('bash', '-c', $command);
一般来说,更重要的是,我会考虑用Perl本身的代码替换shell命令所做的任何操作;结果将更易于管理,并且可能更便于携带和执行。如果设置后打印出$cmd
,您将看到:
echo -e hello
world
。。。如果您将其粘贴到shell中,您将得到类似的错误消息,尽管没有-e
第一个问题是,当它到达shell时,字符串同时缺少引号和非文字换行符。试试这个:
my $str = "hello\\nworld";
my $cmd = "echo -e '$str'";
在这种特殊情况下,您可以只使用引号,因为echo
的参数中会有一个文字换行符,但只要它被引用,这是合法的
但是,您仍然会在输出中获得文本-e
,并且不会将\n
解释为换行符。这是因为perl运行的是/bin/echo
,而不是bash中内置的echo
。如果您想使用bash的内置代码,就必须明确地告诉perl运行bash
。但这意味着将echo命令本身在参数中传递给bash,这将引入另一个级别的引用来处理
这里(实际上,在任何地方)最好的选择是使用多参数版本的系统
;它绕过第一个shell级别并直接执行命令。我们仍然需要处理新线:
my $str = "hello\nworld"; # literal newline
(my $escaped_str = $str) =~ s,\n,\\n,g; # escaped newline
为了从shell中获得所需的行为,我们需要将字符串嵌入shell命令中的单引号中,因为单引号中的任何内容都完全由shell执行。在本例中,我们只是从Perl代码中的一个文本中分配了字符串,因此我们确切地知道它包含什么,并且它不包含撇号。但如果它可能包含撇号,我们应该通过另一个转义过程来引用它们,这样就可以安全地嵌入单引号:
$escaped_str =~ s,','\\'',g; # quote any embedded apostrophes
您可能还希望用转义符替换其他字符—可能是制表符或回车符。这也将是做出这些改变的地方
使用转义字符串生成bash命令:
my $command = "echo -ne '$escaped_str'"; # bash command to echo string
像这样进行手动搜索/替换容易出错;有很多边缘情况需要考虑。因此,您可能还想看看CPAN模块,在该模块中,您可以跳过上面的手动转义,并从原始字符串生成转义字符串,如下所示:
my $command = shell_quote("echo", "-ne", $str);
获得转义命令字符串后,使用多参数system
将该字符串作为参数直接运行bash:
system('bash', '-c', $command);
一般来说,更重要的是,我会考虑用Perl本身的代码替换shell命令所做的任何操作;结果将更易于管理,并且可能更易于移植和性能更好。因为echo-e
不可移植,这是一个特别糟糕的例子。对于任何真实的东西,echo
所能做的一切,您都可以在Perl中更轻松地完成。也许你应该