21

有可能在 bash 脚本中写一个 perl 脚本作为 heredoc 吗

这不起作用(仅示例)

#/bin/bash
perl <<EOF
while(<>) {
    chomp;
    print "xxx: $_\n";
}
EOF

这里有一些如何将 perl 脚本嵌入 bash 脚本的好方法吗?想要从 bash 脚本运行 perl 脚本并且不想将其放入外部文件中。

4

4 回答 4

27

这里的问题是脚本在标准输入上被传递给 perl,所以试图从脚本处理标准输入是行不通的。

1.字符串字面量

perl -e '
while(<>) {
    chomp;
    print "xxx: $_\n";
}
'

使用字符串文字是最直接的编写方式,但如果 Perl 脚本本身包含单引号,这并不理想。

2.使用perl -e

#/bin/bash

script=$(cat <<'EOF'
while(<>) {
    chomp;
    print "xxx: $_\n";
}
EOF
)
perl -e "$script"

如果您将脚本传递给 perl 使用,perl -e那么您将不会遇到标准输入问题,并且您可以在脚本中使用您喜欢的任何字符。不过,这样做有点迂回。Heredocs 在标准输入上产生输入,我们需要字符串。该怎么办?哦,我知道!这要求$(cat <<HEREDOC).

确保使用<<'EOF'而不是仅仅<<EOF阻止 bash 在 heredoc 中进行变量插值。

您也可以在没有$script变量的情况下编写它,尽管它现在变得非常多毛!

perl -e "$(cat <<'EOF'
while(<>) {
    chomp;
    print "xxx: $_\n";
}
EOF
)"

3. 工艺替代

perl <(cat <<'EOF'
while(<>) {
    chomp;
    print "xxx: $_\n";
}
EOF
)

沿着 #2 的思路,您可以使用称为进程替换的 bash 功能,它可以让您<(cmd)代替文件名进行写入。如果你使用它,你就不需要了,-e因为你现在传递给 perl 的是一个文件名而不是一个字符串。

于 2013-07-19T16:39:38.040 回答
4

你知道我从来没有想过这个。

答案是“是的! ”它确实有效。正如其他人所提到的,<STDIN>不能使用,但这很好用:

$ perl <<'EOF'
print "This is a test\n";
for $i ( (1..3) ) {
print "The count is $i\n";
}
print "End of my program\n";
EOF
This is a test
The count is 1
The count is 2
The count is 3
End of my program

在 Kornshell 和 BASH 中,如果用单引号将此处文档字符串的结尾括起来,则此处的文档不会被 shell 插入。

于 2013-07-19T16:50:00.233 回答
2

只是对@John Kugelman 的回答进行了少量修改。您可以消除无用的cat并使用:

read -r -d '' perlscript <<'EOF'
while(<>) {
    chomp;
    print "xxx: $_\n";
}
EOF

perl -e "$perlscript"
于 2013-07-19T16:51:00.597 回答
0

这是在 bash 中使用 PERL HEREDOC 脚本并充分利用它的另一种方法。

    #!/bin/sh
    #If you are not passing bash var's and single quote the HEREDOC tag
    perl -le "$(cat <<'MYPL'
    # Best to build your out vars rather than writing directly
    # to the pipe until the end.
    my $STDERRdata="", $STDOUTdata="";
    while ($i=<STDIN>){ chomp $i;
        $STDOUTdata .= "To stdout\n";
        $STDERRdata .= "Write from within the heredoc\n";
    MYPL
    print $STDOUTdata; #Doing the pipe write at the end
    warn $STDERRdata;  #will save you a lot of frustration.
    )" [optional args] <myInputFile 1>prints.txt 2>warns.txt

或者

    #!/bin/sh
    set WRITEWHAT="bash vars"
    #If you want to include your bash var's
    #Escape the $'s that are not bash vars, and double quote the HEREDOC tag
    perl -le "$(cat <<"MYPL"
    my $STDERRdata="", $STDOUTdata="";
    while (\$i=<STDIN>){ chomp \$i;
        \$STDOUTdata .= "To stdout\n";
        \$STDERRdata .= "Write $WRITEWHAT from within the heredoc\n";
    MYPL
    print \$STDOUTdata; #Doing the pipe write at the end
    warn \$STDERRdata;  #will save you a lot of frustration.
    )" [optional args] <myInputFile 1>prints.txt 2>warns.txt
于 2014-08-25T17:36:23.337 回答