In Perl, the default shell to execute backticks is sh. I'd like to switch to use bash for its richer syntax. So far I found that the suggested solution is
`bash -c \"echo a b\"`
The apparent drawback is that the escaped double quotes, which means I will have difficulty to use double quotes in my bash args. For example, if I wanted to run commands requiring double quotes in bash
echo "a'b"
The above method will be very awkward.
Perl's system() call has a solution for this problem: to use ARRAY args,
system("bash", "-c", qq(echo "a'b"));
This keeps my original bash command unmodified, and almost always.
I'd like to use ARRAY args in backticks too. Is it possible? Thank you for your advice
CodePudding user response:
You can use single quotes as delimiter with qx
like this:
my $out = qx'bash -c "echo a b"';
this will according to perlop protect the command from Perl's double-quote interpolation.
Unfortunately, this does not work for single quotes. If you want to do echo "'"
for example, you need the following:
my $out = `bash -c \"echo \\\"'\\\"\"`;
Edit:
To help you managing the escaping of quotes you could use a helper function like this:
use experimental qw(signatures);
sub bash_backticks($code) {
$code =~ s/'/'"'"'/g;
`bash -c '$code'`
}
CodePudding user response:
I have the following sub that works
sub bash_output {
my ($cmd) = @_;
open my $ifh, "-|", "bash", "-c", $cmd or die "cannot open file handler: $!";
my $output = "";
while (<$ifh>) {
$output .= $_;
}
close $ifh;
return $output;
}
print "test bash_output()\n";
my @strings = (
qq(echo "a'b"),
'echo $BASH_VERSION',
'[[ "abcde" =~ bcd ]] && echo matched',
'i=1; ((i )); echo $i',
);
for my $s (@strings) {
print "bash_output($s) = ", bash_output($s), "\n";
}
The output is
bash_output(echo "a'b") = a'b
bash_output(echo $BASH_VERSION) = 4.4.20(1)-release
bash_output([[ "abcde" =~ bcd ]] && echo matched) = matched
bash_output(i=1; ((i )); echo $i) = 2
My answer is long-winded but it fills my need. I was hoping Perl has a built-in solution just like how it handles system() call and I am still hoping.
CodePudding user response:
You can change the shell used by perl :
$ENV{PERL5SHELL} = "bash";
my $out = qx{echo "Hello ' world from bash \$BASH_VERSION"};
print($out);