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

发布于 2024-09-12 13:09:15 字数 231 浏览 9 评论 0原文

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

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

附言。我尝试运行的命令是:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

站稳脚跟 2024-09-19 13:09:16

这个例子对我有用:

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

This example works for me:

$ perl -e 'print `/bin/bash -c "echo <(pwd)"`'
/dev/fd/63
回忆躺在深渊里 2024-09-19 13:09:16

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

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

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);
你是年少的欢喜 2024-09-19 13:09:16

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

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

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

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?

旧人 2024-09-19 13:09:16

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

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);
囚你心 2024-09-19 13:09:16

我喜欢制作一些函数 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);
}

I like to make some function btck (which integrates error checking) and bash_btck (which uses 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);
}

One of the reasons I like to use bash is for safe pipe behavior:

sub safe_btck ($)
{
    return bash_btck('set -o pipefail && '.shift);
}
呆头 2024-09-19 13:09:15

“系统外壳”通常不是可变的。请参阅 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`;

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`;
笔落惊风雨 2024-09-19 13:09:15

尝试一下

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文