由于我不明白的原因,似乎不可能将定界文档作为表达式传递给 Ruby 解释器:
$ ruby -e <<END
heredoc> puts 'hi'
heredoc> END
ruby: no code specified for -e (RuntimeError)
同样的事情也发生在 Perl 上,令人痛苦的是,它与 Ruby 毫无关系。
$ perl -e<<END
heredoc> print 'hi'
heredoc> END
No code specified for -e.
即使有sed
:
$ echo "blah" | sed -e <<END
pipe heredoc> s/.*/Hi/
pipe heredoc> END
sed: option requires an argument -- e
usage: sed script [-Ealn] [-i extension] [file ...]
sed [-Ealn] [-i extension] [-e script] ... [-f script_file] ... [file ...]
如何将定界符作为表达式传递给 Ruby? (或 Perl,或 Sed...)
答案1
这是因为创建一个巨大的字符串并将其作为参数传递并不是“此处文档”所做的。他们创建一个流,可以连接到某些作业的输入。
具体来说,
cat <<!
foo
!
不等于
cat foo
。
说到这里cat
,它可以帮助我们。警告:非使用cat
以下无用!
echo $(cat <<!
foo
!
)
瞧,我们能传递此处文档作为参数,这要归功于应用于cat
已提供此处文档的命令替换。
答案2
尝试这个:
$ perl -e "$(cat <<'EOF'
print 'qwerty';
EOF
)"
qwerty
您必须使用双引号来perl
了解要运行的程序,并bash
展开此处的文档。
$ perl -MO=Deparse -e "<<'EOF'
print 'qwerty';
EOF
"
'???';
-e syntax OK
您可以看到,perl
您的输入仅作为字符串。
与cat
和process substitution
:
$ perl -MO=Deparse -e "$(cat <<'EOF'
print 'qwerty';
EOF
)
"
print 'qwerty';
-e syntax OK
答案3
-e
需要一个参数,即要执行的代码。您可以使用嵌入换行符的字符串。这对我来说是最具可读性的。适用于 ruby、perl、sed ...
ruby -e '
1.upto(10) do |n|
p [n, n.even?]
end
'
您可以通过 stdin 将 ruby/perl 代码传递给解释器,但是您不能传递任何文件名参数,也不能从 stdin (*) 读取数据
ruby <<'END'
1.upto(10) do |n|
p [n, n.even?]
end
END
(*) 这太恶心了:你可以发送程序和stdin 上的数据,使用 ruby 的(和 Perl 的)DATA 文件句柄:
{
cat <<'END'
while (<DATA>) {print +(split /:/)[0], "\n"}
__END__
END
cat /etc/passwd
} | perl