tags:

views:

4475

answers:

4

How can I use bash syntax in Perl's system() command?

I have a command that is bash-specific, e.g. the following, which uses bash's process substitution:

 diff <(ls -l) <(ls -al)

I would like to call it from Perl, using

 system("diff <(ls -l) <(ls -al)")

but it gives me an error because it's using sh instead of bash to execute the command:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `sort <(ls)'
+5  A: 
 system("bash -c 'diff <(ls -l) <(ls -al)'")

should do it, in theory. Bash's -c option allows you to pass a shell command to execute, according to the man page.

David Zaslavsky
+23  A: 

Tell Perl to invoke bash directly. Use the list variant of system() to reduce the complexity of your quoting:

my @args = ( "bash", "-c", "diff <(ls -l) <(ls -al)" );
system(@args);

You may even define a subroutine if you plan on doing this often enough:

sub system_bash {
  my @args = ( "bash", "-c", shift );
  system(@args);
}

system_bash('echo $SHELL');
system_bash('diff <(ls -l) <(ls -al)');

Cheers, V.

vladr
+1 for using the list variant
David Zaslavsky
This also prevents you from invoking /bin/sh just to run bash
cjm
I agree, the list variant is nice.
A: 

I had a similar question with Python's equivalent in "In python 2.4, how can I execute external commands with csh instead of bash?". hop's answer was rather insightful. It could apply to Perl as well.

Ross Rogers
Going messing with the system /bin/sh is inviting trouble.
Jonathan Leffler
I agree, but its useful to know why you can't use bash. Personally, I ended up using the bash -c 'cmd' form. But the "bash -c" puts you in the awkward position of either telling your users (if you care, as I do) what shell cmd you're _actually_ running vs what the original, un-escaped command is.
Ross Rogers
And you don't need to, because Perl has system LIST, which lets you run whatever program you want without having to mess with the default system shell and its quoting syntax. Even if that program happens to be a different shell.
cjm
A: 

THe world outside of Linux that doesn't want to have to install bash to run Perl programs thanks you.

MkV
Haha, that's okay. Fortunately, I'm the only one who will run this. It's a typical Perl throw-away thing.
Hey, thanks a bunch Andrew. I couldn't find a way to edit out the sarcasm for you though.
MkV