bash 的 HereDoc 中的 Perl 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17751199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Perl script in bash's HereDoc
提问by Nemo
Is possible somewhatwrite a perl script in a bash script as heredoc?
可能有些写在bash脚本定界符一个Perl脚本?
This is not working (example only)
这不起作用(仅示例)
#/bin/bash
perl <<EOF
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
Is here some nice way how to embed a perl script into a bash script? Want run perl script from an bash script and don't want put it into external file.
这里有一些很好的方法如何将 perl 脚本嵌入到 bash 脚本中?想要从 bash 脚本运行 perl 脚本并且不想将它放入外部文件中。
回答by John Kugelman
The problem here is that the script is being passed to perl on stdin, so trying to process stdin from the script doesn't work.
这里的问题是脚本被传递到标准输入上的 perl,所以试图从脚本处理标准输入是行不通的。
1. String literal
1. 字符串字面量
perl -e '
while(<>) {
chomp;
print "xxx: $_\n";
}
'
Using a string literal is the most direct way to write this, though it's not ideal if the Perl script contains single quotes itself.
使用字符串字面量是最直接的写法,但如果 Perl 脚本本身包含单引号,这并不理想。
2. Use perl -e
2. 使用 perl -e
#/bin/bash
script=$(cat <<'EOF'
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
)
perl -e "$script"
If you pass the script to perl using perl -ethen you won't have the stdin problem and you can use any characters you like in the script. It's a bit roundabout to do this, though. Heredocs yield input on stdin and we need strings. What to do? Oh, I know! This calls for $(cat <<HEREDOC).
如果您将脚本传递给 perl using,perl -e那么您将不会遇到 stdin 问题,并且您可以在脚本中使用您喜欢的任何字符。不过,这样做有点迂回。Heredocs 在 stdin 上产生输入,我们需要字符串。该怎么办?哦,我知道!这要求$(cat <<HEREDOC).
Make sure to use <<'EOF'rather than just <<EOFto keep bash from doing variable interpolation inside the heredoc.
确保使用<<'EOF'而不是仅仅<<EOF防止 bash 在 heredoc 中进行变量插值。
You could also write this without the $scriptvariable, although it's getting awfully hairy now!
你也可以在没有$script变量的情况下写这个,虽然它现在变得非常毛茸茸!
perl -e "$(cat <<'EOF'
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
)"
3. Process substitution
3. 工艺替代
perl <(cat <<'EOF'
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
)
Along the lines of #2, you can use a bash feature called process substitution which lets you write <(cmd)in place of a file name. If you use this you don't need the -esince you're now passing perl a file name rather than a string.
沿着 #2 的路线,您可以使用称为进程替换的 bash 功能,它可以让您<(cmd)代替文件名写入。如果您使用它,则不需要 ,-e因为您现在向 perl 传递文件名而不是字符串。
回答by David W.
You know I never thought of this.
你知道我从来没有想过这个。
The answer is "YES!" it does work. As others have mentioned, <STDIN>can't be used, but this worked fine:
答案是“是的!”它确实有效。正如其他人提到的,<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
In Kornshell and in BASH, if you surround your end of here document string with single quotes, the here document isn't interpolated by the shell.
在 Kornshell 和 BASH 中,如果您用单引号将 here 文档字符串的结尾括起来,则 shell 不会插入 here 文档。
回答by jm666
Only small corection of @John Kugelman's answer. You can eliminate the useless catand use:
仅对@John Kugelman 的回答进行了少量修正。您可以消除无用的cat并使用:
read -r -d '' perlscript <<'EOF'
while(<>) {
chomp;
print "xxx: $_\n";
}
EOF
perl -e "$perlscript"
回答by Dave Cronin
Here's another way to use a PERL HEREDOC script within bash, and take full advantage it.
这是在 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
or
或者
#!/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

