入力リダイレクトの場合、bash/zsh <<<"$(

入力リダイレクトの場合、bash/zsh <<<"$(

私はファイルからの伝統的な入力リダイレクトと似たような効果がある使い方についてだけ尋ねています。

<<<"$(<file)"

私が知る限り、それは次のとおりです。

<file

私の考えでは、これらは機能的に同じです。低いレベルでは、<<<この文書は実際には同時にメモリにより多くのデータコピーを作成できます。

このタイプのリダイレクトがbashとzshの両方に存在することを知っていますが、zshのマニュアルページにいくつかの実装の詳細が含まれていますが、実装方法については慣れていません。

答え1

(Byron RakitzisのUnixクローンの同じ演算子からインスピレーションを得た(ここでは、この演算子は)and)によって最初に導入されました<<<"$(<file)"zsh<<<rcksh93$(<file)kshmkshbash

$(<file)シェルが内容を読み取るとfile(ブロックされたNULバイトを除くzsh)、すべての末尾の改行が削除されて拡張されます$(<file)(したがって、ファイル全体の内容がメモリに保存されます)。

の場合、<<< some-textシェルはsome-text改行文字とそれに続く改行文字を一時ファイルに保存し、ファイル記述子0で一時ファイルを開きます(最近のバージョンを含む一部のシェルでは、少なくとも少量のbashデータに対して代わりにパイプを使用できます)。

したがって、デフォルトでは、末尾の改行文字を<<<"$(<file)"読み取るためにstdinを開くことは一時コピーfileにのみ置き換えられます(ファイルにNULバイトが含まれていると、すべての種類の誤動作が発生しますzsh)。

では、標準入力から読み取るために直接開きます< filefile

もちろん、より効率的ですが(ディスクとメモリ内のコピーは含まれていません)、stdinで開かれたファイルが次のようになっていることを確認したい< file場合があります。<<<"$(<file)"定期的なコマンドの開始時にファイルが完全に読み込まれたことを確認するか(コマンドがファイルに書き込む場合など)、他のリダイレクト(切り捨てリダイレクトなど)fileを処理しますtr 1 2 <<< "$(<file)" > file

演算子がyashサポートされていることに注意してください(パイプを使用して実装されているにもかかわらず(したがってサポートされていません)。<<<定期的なファイル)の代わりに一時ファイル)を使用します。しかし、そうでは$(<file)ありません。<<<"$(cat < file)"そこで使用してください。yash文字列は単なる文字であるため、"$(cat < file)"有効な文字を形成しないバイトシーケンスをブロックしますが、他のシェルは通常これを正常に処理できます。

答え2

次のコマンドはすべてファイルの(txt)内容を作成します(バイナリファイルでは試みません)。

cat        file
cat       <file
echo   "$(<file)"
cat <<<"$(<file)"

しかし、これはcatが適応可能なコマンドであるため、コマンドが同じであるためではありません。

  1. このコマンドはcat fileファイルの内容を印刷します。この場合、catは実際のファイルで動作します。似ているless file。ただし、少ないほど実際のファイルが必要です。

  2. このコマンドは、cat <fileストリームに抽出されたファイルの内容を標準入力からストリームを受け取るcatに供給します。しかし、catはこれに問題はありません。また、ストリームを印刷して同じ結果を見ることができます。

  3. この場合はecho "$(<file)"まったく"$(< file)"同じです(一部のサブシェルの詳細を除く)"$(cat file)"。これはcatコマンドが実行されたことを意味します。その後、出力はコマンド実行によってテキスト文字列に変換され、$(...)最後にテキスト文字列はエコーを介して印刷されます。ファイルの内容を再表示します。

  4. コマンドはcat <<<"$(<file)"次の順序に従います。

    • "$(<file)"ファイルを読み込み、文字列として出力します。

    • <<<標準入力(stdin)に文字列を送信する

    • catは入力(stdin)から受け取った内容を印刷します。

同じファイルの内容が表示されます。

結論として

すべての場合で同じ結果が表示されます。ただし、ファイルの内容は、コマンドのすべての部分で「その内容」(ファイル名、ストリーム、文字列など)を変更します。

関連情報