perl反引号:使用bash而不是sh

时间:2010-07-30 17:44:11

标签: perl bash shell sh backticks

我注意到当我在perl中使用反引号时,命令是使用sh而不是bash执行的,这给我带来了一些问题。

如何改变这种行为,以便perl使用bash?

PS。我正在尝试运行的命令是:

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

6 个答案:

答案 0 :(得分:7)

“系统shell”通常不可变。见perldoc -f exec

  

如果LIST中有多个参数,或者LIST是一个具有多个值的数组,则使用LIST中的参数调用execvp(3)。如果   只有一个标量参数或一个包含一个元素的数组,参数检查是否为shell元字符,如果有,则为   整个参数传递给系统的命令shell进行解析(在Unix平台上这是“/ bin / sh -c”,但在其他平台上有所不同)。

如果您真的需要bash来执行特定任务,请考虑明确调用它:

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

甚至:

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

您也可以将bash命令放入.sh文件中并直接调用它:

my $result = `/usr/bin/bash script.pl`;

答案 1 :(得分:7)

尝试

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

我很确定-c的参数被解释为bash解释其命令行的方式。诀窍是保护它不受sh的影响 - 这就是引用的目的。

答案 2 :(得分:5)

此示例适用于我:

$ perl -e 'print `/bin/bash -c "echo <(pwd)"`'
/dev/fd/63

答案 3 :(得分:1)

为了处理运行bash和嵌套引号,本文提供了最佳解决方案:How can I use bash syntax in Perl's system()?

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

答案 4 :(得分:0)

我认为perl会尊重$SHELL变量,但后来我发现它的行为可能实际上取决于系统的exec实现。在我看来,似乎是exec

  

将执行shell   (/ bin / sh)的路径   将file作为其第一个参数。

你总是可以qw/bash your-command/,不是吗?

答案 5 :(得分:0)

创建一个perl子例程:

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

并使用如下:

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

或者使用perl here-doc进行多行命令:

$bash_cmd = <<'EOF';
    for (( i = 0; i < 10; i++ )); do
       echo "${i}"
    done
EOF
print &bash($bash_cmd);