views:

162

answers:

4

Hi,

I noticed that when I use backticks in perl the commands are executed using sh, not bash, giving me some problems.

How can I change that behavior so perl will use bash?

PS. The command that I'm trying to run is:

paste filename <(cut -d \" \" -f 2 filename2 | grep -v mean) >> filename3
+4  A: 

The "system shell" is not generally mutable. See perldoc -f exec:

If there is more than one argument in LIST, or if LIST is an array with more than one value, calls execvp(3) with the arguments in LIST. If there is only one scalar argument or an array with one element in it, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is "/bin/sh -c" on Unix platforms, but varies on other platforms).

If you really need bash to perform a particular task, consider calling it explicitly:

my $result = `/usr/bin/bash command arguments`;

or even:

open my $bash_handle, '| /usr/bin/bash' or die "Cannot open bash: $!";
print $bash_handle 'command arguments';

You could also put your bash commands into a .sh file and invoke that directly:

my $result = `/usr/bin/bash script.pl`;
Ether
I still can't get the expected behavior. The reason I wanted bash is that I run ac command using <(grep ...) and it seems sh does not support it (but bash does). If I run my command as a user, directly from bash it works fine. If I run it from perl in backticks then sh shouts "sh: Syntax error: "(" unexpected", if I run it in backticks preceded by /usr/bin/bash I still get the same thing from sh.
David B
@David: I don't quite understand what command you're trying to run; can you edit that into your question with code formatting?
Ether
@Ether: just did it :)
David B
A: 

I thought perl would honor the $SHELL variable, but then it occurred to me that its behavior might actually depend on your system's exec implementation. In mine, it seems that exec

will execute the shell (/bin/sh) with the path of the file as its first argument.

You can always do qw/bash your-command/, no?

Pedro Silva
I still get "sh: Syntax error: "(" unexpected". See a comment on the original post for the command I try to run.
David B
+3  A: 

This example works for me:

$ perl -e 'print `/bin/bash -c "echo <(pwd)"`'
/dev/fd/63
Dennis Williamson
this works for me, too...
David B
+4  A: 

Try

`bash -c \"your command with args\"`

I am fairly sure the argument of -c is interpreted the way bash interprets its command line. The trick is to protect it from sh - that's what quotes are for.

Arkadiy
Now I'm getting errors like -f 1 /tmp/file | grep -v mean) >> /tmp/file2: -c: line 0: unexpected EOF while looking for matching `)' -f 1 /tmp/file3 | grep -v mean) >> /tmp/file4: -c: line 1: syntax error: unexpected end of file
David B
May be \ aren't needed in my example. Also, don't use " inside your command - use ' .
Arkadiy
SOLVED! The only thing that worked for me was: `\`bash -c 'my_command'\``
David B
You could also evade quoting problems by using `open my $fh, '-|', qw(bash -c), $cmdline` which is pretty much guaranteed to work exactly as \`$cmdline\` -- but the interface is different.
hobbs