perl backticks: use bash instead of sh

前端 未结 6 1603
南笙
南笙 2021-01-05 11:20

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 ba

相关标签:
6条回答
  • 2021-01-05 11:45

    This example works for me:

    $ perl -e 'print `/bin/bash -c "echo <(pwd)"`'
    /dev/fd/63
    
    0 讨论(0)
  • 2021-01-05 11:50

    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.

    0 讨论(0)
  • 2021-01-05 11:56

    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?

    0 讨论(0)
  • 2021-01-05 11:58

    To deal with running bash and nested quotes, this article provides the best solution: How can I use bash syntax in Perl's system()?

    my @args = ( "bash", "-c", "diff <(ls -l) <(ls -al)" );
    system(@args);
    
    0 讨论(0)
  • 2021-01-05 12:05

    Create a perl subroutine:

    sub bash { return `cat << 'EOF' | /bin/bash\n$_[0]\nEOF\n`; }
    

    And use it like below:

    my $bash_cmd = 'paste filename <(cut -d " " -f 2 filename2 | grep -v mean) >> filename3';
    print &bash($bash_cmd);
    

    Or use perl here-doc for multi-line commands:

    $bash_cmd = <<'EOF';
        for (( i = 0; i < 10; i++ )); do
           echo "${i}"
        done
    EOF
    print &bash($bash_cmd);
    
    0 讨论(0)
  • 2021-01-05 12:06

    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`;
    
    0 讨论(0)
提交回复
热议问题