是否有可能稍微在bash脚本中编写perl脚本作为heredoc?
这不起作用(仅限示例)
#/bin/bash
perl <<EOF
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
这里有一些很好的方法如何将perl脚本嵌入到bash脚本中?想从bash脚本运行perl脚本,不要把它放到外部文件中。
答案 0 :(得分:22)
这里的问题是脚本是在stdin上传递给perl的,所以尝试从脚本处理stdin不起作用。
perl -e '
while(<>) {
chomp;
print "xxx: $_\n";
}
'
使用字符串文字是最直接的写法,但如果Perl脚本本身包含单引号则不理想。
perl -e
#/bin/bash
script=$(cat <<'EOF'
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
)
perl -e "$script"
如果您使用perl -e
将脚本传递给perl,那么您将不会遇到stdin问题,并且您可以在脚本中使用您喜欢的任何字符。不过,要做到这一点有点迂回。 Heredocs在stdin上产生输入,我们需要字符串。该怎么办?哦,我知道!这需要$(cat <<HEREDOC)
。
请务必使用<<'EOF'
而非<<EOF
来阻止bash在heredoc中进行变量插值。
你也可以在没有$script
变量的情况下写这个,虽然它现在变得非常毛茸茸!
perl -e "$(cat <<'EOF'
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
)"
perl <(cat <<'EOF'
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
)
沿着#2行,您可以使用称为进程替换的bash功能,它允许您编写<(cmd)
来代替文件名。如果你使用它,你不需要-e
,因为你现在传递perl文件名而不是字符串。
答案 1 :(得分:3)
你知道我从没想过这个。
答案是“是!”它确实有效。正如其他人所提到的,<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不会插入here文档。
答案 2 :(得分:2)
只有@John Kugelman的小修正回答。你可以消除无用的cat
并使用:
read -r -d '' perlscript <<'EOF'
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
perl -e "$perlscript"
答案 3 :(得分: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