9

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

我怎样才能改变这种行为,以便 perl 将使用 bash?

PS。我试图运行的命令是:

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

6 回答 6

8

尝试

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

我相当确定 -c 的参数被解释为 bash 解释其命令行的方式。诀窍是保护它免受sh- 这就是引号的用途。

于 2010-07-30T18:16:52.433 回答
8

“系统外壳”通常不是可变的。请参阅perldoc -f exec

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

如果您确实需要 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`;
于 2010-07-30T18:00:19.040 回答
5

这个例子对我有用:

$ perl -e 'print `/bin/bash -c "echo <(pwd)"`'
/dev/fd/63
于 2010-07-30T18:16:18.660 回答
1

为了处理运行 bash 和嵌套引号,本文提供了最佳解决方案:如何在 Perl 的 system() 中使用 bash 语法?

my @args = ( "bash", "-c", "diff <(ls -l) <(ls -al)" );
system(@args);
于 2014-12-09T20:30:45.620 回答
0

我以为perl会尊重该$SHELL变量,但后来我想到它的行为实际上可能取决于您系统的exec实现。在我看来,exec

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

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

于 2010-07-30T18:00:56.607 回答
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);
于 2013-09-05T01:36:58.253 回答