Perl executes only part of the shell command and issues a warning "excessive argument to printf" when command substitution

The following testing was tested with perl 5.24 on OS X 10.11.5.

I wrote a short program ( perl-embed.pl) to determine if perl removes shell metacharacters when interpolating strings to backward measures (this is not the case).

use strict;
use warnings;

my $bar = '" ; echo 45 ; "';

printf "%s\n", `echo "hi${bar}ls"`;

I was very surprised to see that this caused a warning and only completed part of the team.

$ perl perl-embed.pl
Redundant argument in printf at perl-embed.pl line 6.
hi

For comparison, the following program ( perl-embed2.pl) with printinstead of printfrunning without warning.

use strict;
use warnings;

my $bar = '" ; echo 45 ; "';

print `echo "hi${bar}ls"`;

Then I launched it.

$ perl perl-embed2.pl
hi
45
<contents of current working directory>

perl-embed.plthe behavior is completely unexpected. printfinterpolates the contents of the strings just fine in other contexts, even if the string contains strange characters.

$ 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 .

+4
1

backticks ,

`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'
+2

All Articles