在OS X 10.11.5上使用perl 5.24测试了以下内容。
我编写了一个简短的程序(perl-embed.pl
),以确定在将字符串插入反引号时perl是否会转义shell元字符(它不会)。
use strict;
use warnings;
my $bar = '" ; echo 45 ; "';
printf "%s\n", `echo "hi${bar}ls"`;
我很惊讶地看到这产生了一个警告,只执行了部分命令。
$ perl perl-embed.pl
Redundant argument in printf at perl-embed.pl line 6.
hi
为了进行比较,以下perl-embed2.pl
代替print
的程序(printf
)会在没有警告的情况下运行。
use strict;
use warnings;
my $bar = '" ; echo 45 ; "';
print `echo "hi${bar}ls"`;
然后我跑了。
$ perl perl-embed2.pl
hi
45
<contents of current working directory>
perl-embed.pl
的行为完全出乎意料。 printf
在其他上下文中插入字符串的内容就好了,即使字符串包含奇怪的字符。
$ perl -Mstrict -Mwarnings -e 'printf "%s\n", q[5]'
5
$ perl -Mstrict -Mwarnings -e 'printf "%s\n", q["]'
"
系统perl(版本5.18)不会发出此警告,但似乎不会像我们期望的那样执行ls
或echo 45
$ /usr/bin/perl perl-embed.pl
hi
$ /usr/bin/perl perl-embed2.pl
hi
45
<contents of current directory>
为什么perl会这样表现?请注意,在每种情况下perl都会正常退出。
答案 0 :(得分:2)
您在列表上下文中使用反引号,因此表达式
`echo "hi${bar}ls`
将运行命令
`echo "hi"; echo 45; ls`
并在单独的元素中返回每行输出,例如
( "hi",
"45",
"foo",
... # other files in current directory
)
但printf
("%s\n"
)中的模板只有一个占位符,因此printf
会混淆并发出警告,就像您说的那样
perl -we 'printf "%d\n", 1, 2, 3, 4'