HEREDOCを "ruby -e"に文字列として渡すことができないのはなぜですか?

HEREDOCを "ruby -e"に文字列として渡すことができないのはなぜですか?

理解できない理由で区切られた文書を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提供されたhereドキュメントに適用されたコマンドの置き換えのおかげで、hereドキュメントをパラメータとして渡します。

答え2

この試み:

$ perl -e "$(cat <<'EOF'
print 'qwerty';
EOF
)"
qwerty

perl実行したいプログラムを確認するには二重引用符を使用し、bashここで文書を拡張する必要があります。

$ perl -MO=Deparse -e "<<'EOF'
print 'qwerty';
EOF
"
'???';
-e syntax OK

perl入力が文字列でのみ行われることがわかります。

そして:catprocess substitution

$ perl -MO=Deparse -e "$(cat <<'EOF'
print 'qwerty';
EOF
)
"
print 'qwerty';
-e syntax OK

答え3

-e実行するコードである引数が1つ必要です。改行文字を含む文字列を使用できます。これは私にとって最も読みやすいです。 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

(*)これは嫌なことです。プログラムを送信できます。そしてRuby(およびPerl)のDATAファイルハンドルを使用するstdinのデータ:

{
    cat <<'END'
while (<DATA>) {print +(split /:/)[0], "\n"}
__END__
END
    cat /etc/passwd
} | perl

関連情報