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_IOS
unsetopt MULT_IOS
$ cat << E1 << E2
heredoc> foo
heredoc> E1
heredoc> bar
heredoc> E2
foo
bar
cat
stdin はパイプで、zsh はパイプのもう一方の端で 2 つの here ドキュメントの内容を順番に提供します。
出力リダイレクトにも同様の機能があります。
ls > a > b
ls
パイプに書き込む間、zshは同時にa
書いて書きb
ます(形式に似ていますtee
)。一方、他のシェルのls
stdoutは切り捨てられますb
(a
カットされますが記録されません)。
答え2
cat
引数がない場合は、ファイルの最後まで標準入力(ファイル記述子0など)を読み取り、それを標準出力(ファイル記述子1など)にコピーします。
cat
1 つ以上の引数を使用すると、その引数を順番に入力として開き、データを標準出力にコピーしようとします。この場合、標準入力を無視します。ctrlたとえば、次の操作を行った後に+を入力する必要がある場合は非常に迷惑になる可能性があるため、これは良いことです。これは、ファイル名が指定されたときに「ここ」文書が無視される理由を説明します。特別な場合には、「標準入力」を意味すると解釈されるファイル名を指定できます。Dcat /etc/motd
cat
-
できるファイルを「ここ」文書とマージします。
シェルはファイルをコマンドに標準入力としてのみ渡すことができるため、2つの「ここ」文書をコマンドに渡すことは意味がありません。実際には、最後の文書だけがコマンドに標準入力として渡されます。
答え3
コマンドの標準入力(stdin
)をリダイレクトする方法はいくつかあります。
command <file
単純リダイレクト:stdinはファイルになります。command <&n
fd
他の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
一部のシェルは追加の形式のリダイレクトを提供します。たとえば、 とbash
はksh
"zsh
ここで文字列" を提供することができます: command <<<word
。
答え4
どこに役立つかはわかりませんが:
cat <<HERE
qwer
asdf
$(cat <<ALT
zxcv
yuop
ALT
)
HERE