ヒアドキュメントをパイプするための複数行の構文。これはポータブルですか?


132

私はこの構文に精通しています:

cmd1 << EOF | cmd2
text
EOF

しかし、bashを使用すると次のように記述できることがわかりました。

cmd1 << EOF |
text
EOF
cmd2

(ヒアドキュメントはcmd1への入力として使用され、cmd1の出力はcmd2にパイプされます)。これは非常に奇妙な構文のようです。ポータブルですか?


これを複数行に分割する良い方法を見つけるためにここに来ました: big-long-command1 with lots of args << EOF | big-long-command2 with lots of args。「奇数構文」が最良の方法のようです。
PaulC、2014

これの便利な使用例の1つは、スペースで区切られたテーブルをタブ区切りのテーブルに変換して、Googleスプレッドシートに貼り付ける場合です。一時ファイルを作成する必要はありません。
Sridhar Sarnobat

1つ目はz-shellでは機能しませんでした。2つ目は疎外されるため、私は好きではありません。コマンドから、シェルパイプラインのイディオマシー(?)が失われます。
Sridhar Sarnobat

回答:


104

はい、POSIX標準ではこれが可能です。 2008年のバージョンによると:

here-documentは、次の単語の後に始まり<newline>、区切り文字とaのみを含み、間に文字が<newline>ない行があるまで続く単一の単語として扱われ<blank>ます。次に、次のヒアドキュメントがあれば開始します。

そして、同じ行に複数の「ヒアドキュメント」のこの例が含まれています:

cat <<eof1; cat <<eof2
Hi,
eof1
Helene.
eof2

したがって、リダイレクトやパイプを実行しても問題はありません。あなたの例は次のようなものに似ています:

cat file |
cmd

また、シェルの文法(リンクされたページのさらに下)には、次の定義が含まれています。

pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command

newline_list     :              NEWLINE
                 | newline_list NEWLINE
                 ;
linebreak        : newline_list
                 | /* empty */

そのため、パイプシンボルの後には行末が続き、パイプラインの一部と見なされます。


26

はい、それはPOSIXシェルの文法にあります。同じコマンドに対して複数のhere-docを使用することもできます(他の例では2つのcat呼び出しを使用しますが、これも機能します)。

cat <<EOF1 <<EOF2
first here-doc
EOF1
second here-doc
EOF2

これは工夫されていますが(stdinに2つのhere-docsを使用)、さまざまなファイル記述子に入力を提供することを考えている場合は、すぐに理解できます。

完全落とすcat可能性もあります。ヒアドキュメントを直接利用できるようにしないでcmdください:

cmd << EOF
input
here
EOF

`` `cat << EOF1 << EOF2 first here-doc EOF1 second here-doc EOF2` ``上記は機能しません。
user1424739

@ user1424739現在のzshとbashで動作します。ashとksh93は、2番目のhereドキュメントのみを出力するようです。
Jens

なぜ反対票か。不正確な点がある場合は、是正の機会をください。
Jens

これはを使うとかなり甘いsudo tee /etc/securefile.conf <<EOFです。
dragon788 '19

どのbashバージョンで動作しますか?bash 4.4.19(ubuntu 18.04.02)とbash 5.0(docker image)を使用して、2番目のhere-docのみを取得しました。それとも特定のオプションがありますか?
huelbois

17

うーん、POSIXモードでのbashのテストによると、そうだと思います。

$ bash --posix
$ cat <<EOF |
> ahoj
> nazdar
> EOF
> sed 's/a/b/'
bhoj
nbzdar

もう1つの小さなメモ:閉会後にスペースを入れないでくださいEOF。プロンプトの動作がおかしくなり、一体何が悪いのか不思議に思うでしょう
Sridhar Sarnobat

2
POSIXモードでbashを実行すると、一部の拡張機能が遮断されますが、ほぼすべての拡張機能が遮断されることはありません。そのため、この回答はPOSIXが許可するものに関しては正しいですが、その推論はそれを非常に効果的にサポートしていません。
Charles Duffy

3

こんにちは、例えばこれをチェックしてください

#!/bin/sh
( base32 -d | base64 -d )<<ENDOFTEXT
KNDWW42DNNSHS5ZXPJCG4MSVM5MVQVT2JFCTK3DELBFDCY2IIJYGE2JUJNHWS22LINVHQMCMNVFD
CWJQIIZVUV2JOVNEOVJLINTW6PIK
ENDOFTEXT

よろしく

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.