2つのheredocを猫にする方法は? [コピー]

2つのheredocを猫にする方法は? [コピー]

catに2つのheredocが与えられると、2番目の文書のみを出力します。

$ cat <<HERE
> adsf
> qwer
> HERE
adsf
qwer
$ cat <<HERE <<ALT
> qwer
> asdf
> HERE
> zxcv
> yuop
> ALT
zxcv
yuop

これは、区切り文字とファイルが与えられたときにも機能します。ファイルと区切り記号(逆順)を与えると、まだファイルだけを出力することがわかりました。ただし、cat 2つのファイルを指定すると、両方のファイルが正しく出力されます。

猫はなぜこのような行動をするのですか?

答え1

システムから/dev/fd/x

cat - << E0 /dev/fd/3 3<< E3
foo bar
E0
bar baz
E3

つまり、2つを開きます。ここにファイル別のファイル記述子にあります。 fd 0で開くと、もちろん最後に開いたものが前のものを上書きします。

上記のコマンドは、このようなコマンドでより便利ですpaste

次の機能(デフォルトで有効になっており、他のシェルをエミュレートするときは無効)zshに注意してください。入力のファイル記述子を複数回リダイレクトすると、zshはその入力の接続を提供します(別々のプロセスのパイプを介して)。だからzshでは:MULT_IOSunsetopt MULT_IOS

$ cat << E1 << E2
heredoc> foo
heredoc> E1
heredoc> bar
heredoc> E2
foo
bar

catstdin はパイプで、zsh はパイプのもう一方の端で 2 つの here ドキュメントの内容を順番に提供します。

出力リダイレクトにも同様の機能があります。

ls > a > b

lsパイプに書き込む間、zshは同時にa書いて書きbます(形式に似ていますtee)。一方、他のシェルのlsstdoutは切り捨てられますbaカットされますが記録されません)。

答え2

cat引数がない場合は、ファイルの最後まで標準入力(ファイル記述子0など)を読み取り、それを標準出力(ファイル記述子1など)にコピーします。

cat1 つ以上の引数を使用すると、その引数を順番に入力として開き、データを標準出力にコピーしようとします。この場合、標準入力を無視します。ctrlたとえば、次の操作を行った後に+を入力する必要がある場合は非常に迷惑になる可能性があるため、これは良いことです。これは、ファイル名が指定されたときに「ここ」文書が無視される理由を説明します。特別な場合には、「標準入力」を意味すると解釈されるファイル名を指定できます。Dcat /etc/motdcat-できるファイルを「ここ」文書とマージします。

シェルはファイルをコマンドに標準入力としてのみ渡すことができるため、2つの「ここ」文書をコマンドに渡すことは意味がありません。実際には、最後の文書だけがコマンドに標準入力として渡されます。

答え3

コマンドの標準入力(stdin)をリダイレクトする方法はいくつかあります。

  • command <file 単純リダイレクト:stdinはファイルになります。
  • command <&nfd他のfdについて繰り返し:stdinはnの繰り返しになります。
  • command <<word ここにドキュメントがあります:stdinがスクリプトになります。word
  • other | command パイプ:stdinは出力から来ます。other

stdinが1つしかないので、stdinへのリダイレクトは1つだけ機能します。単純なルールは最後のエントリが勝つということです(これらはすべて順次適用されますが、リダイレクトにfd冗長性が含まれている場合は重要です)。

上記の最後の形式は、複数の入力を接続する簡単な方法を提供します。

{ cat <<END; cat <<END; } | command
The first here-doc
END
The second here-doc
END

一部のシェルは追加の形式のリダイレクトを提供します。たとえば、 とbashksh"zshここで文字列" を提供することができます: command <<<word

答え4

どこに役立つかはわかりませんが:

cat <<HERE
qwer
asdf
$(cat <<ALT
zxcv
yuop
ALT
)
HERE

関連情報