perl反勾号:使用bash代替sh

ergxz8rk  于 2023-01-09  发布在  Perl
关注(0)|答案(7)|浏览(185)

我注意到当我在perl中使用反勾号时,命令是使用sh而不是bash执行的,这给我带来了一些问题。
我怎样才能改变这种行为,使perl使用bash?
PS.我尝试运行的命令是:

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

hmae6n7t1#

"系统shell"通常是不可变的。请参见perldoc -f exec
如果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`;
0sgqnhkj

0sgqnhkj2#

试试看

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

我相当肯定-c的参数是像bash解释它的命令行那样解释的,诀窍是保护它不受sh的影响--这就是引号的作用。

dw1jzc5e

dw1jzc5e3#

这个例子对我很有效:

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

wrrgggsh4#

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

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

8mmmxcuj5#

我原以为perl会荣誉$SHELL变量,但后来我突然想到,它的行为实际上可能取决于系统的exec实现。
将执行shell(/bin/sh),并将文件路径作为其第一个参数。
你总是可以做qw/bash your-command/的,不是吗?

z4bn682m

z4bn682m6#

创建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);
gg0vcinb

gg0vcinb7#

我想创建一些函数btck(集成了错误检查)和bash_btck(使用bash):

use Carp;

sub btck ($)
{
    # Like backticks but the error check and chomp() are integrated

    my $cmd = shift;
    my $result = `$cmd`;
    $? == 0 or confess "backtick command '$cmd' returned non-zero";
    chomp($result);
    return $result;
}

sub bash_btck ($)
{
    # Like backticks but use bash and the error check and chomp() are
    # integrated

    my $cmd = shift;
    my $sqpc = $cmd;   # Single-Quote-Protected Command
    $sqpc =~ s/'/'"'"'/g;
    my $bc = "bash -c '$sqpc'";
    return btck($bc);
}

我喜欢使用bash的原因之一是为了安全管道行为:

sub safe_btck ($)
{
    return bash_btck('set -o pipefail && '.shift);
}

相关问题