$(<file)(これも動作します`<file`)は、zshとによってコピーされたKornシェルの特殊な演算子ですbash。コマンド置換によく似ていますが、実際はそうではありません。
POSIXシェルでは、簡単なコマンドは次のとおりです。
< file var1=value1 > file2 cmd 2> file3 args 3> file4
すべてのパーツはオプションであり、リダイレクトのみ、コマンドのみ、割り当てのみ、または組み合わせが可能です。
リダイレクトはあるがコマンドがない場合、リダイレクトは実行されます(つまり、> fileが開いて切り捨てられますfile)が、何も起こりません。そう
< file
file読み取り用に開きますが、コマンドがないため何も起こりません。だから、fileそれは閉じられ、それだけです。$(< file)単純なコマンド置換であれば、何にも拡張されません。
でPOSIX仕様で$(script)、場合scriptのみ、リダイレクションの構成され、それは、不特定の結果を生成します。これは、Kornシェルの特別な動作を可能にするためです。
ksh(ここではでテストksh93u+)で、スクリプトがリダイレクト(コマンドなし、割り当てなし)のみで構成される1つだけの単純なコマンド(コメントは前後に許可されます)で構成され、最初のリダイレクトがstdin(fd 0)入力のみ(<、<<または<<<)リダイレクトなので、
$(< file)
$(0< file)
$(<&3)(また、$(0>&3)実際には同じ演算子なので)
$(< file > foo 2> $(whatever))
だがしかし:
$(> foo < file)
- また
$(0<> file)
- また
$(< file; sleep 1)
- また
$(< file; < file2)
その後
- 最初のリダイレクト以外はすべて無視されます(それらは解析されます)
- そして、それはfile / heredoc / herestring(またはのようなものを使用している場合はファイル記述子から読み取ることができるもの
<&3)の内容から末尾の改行文字を除いたものに展開されます。
それ$(cat < file)以外は使うかのように
- 読み取りはシェルではなく内部で行われます
cat
- パイプも余分なプロセスも含まれていません
- 上記の結果として、内部のコードはサブシェルで実行されないため、変更はその後も残ります(
$(<${file=foo.txt})または$(<file$((++n))))
- 読み取りエラー(ファイルを開いているときやファイル記述子を複製しているときのエラーではありません)は警告なしに無視されます。
zshそれだけで一つのファイル入力のリダイレクトがありますときには、特別な行動が唯一のトリガされたことを除いて同じです(<fileまたは0< file、なし<&3、<<<here、< a < b...)
ただし、他のシェルをエミュレートする場合を除いて:
< file
<&3
<<< here...
それは、コマンドなしでのみ入力リダイレクション、コマンド置換の外側がある場合には、zsh実行されます$READNULLCMD(デフォルトではページャ)を、両方の入力と出力のリダイレクトが、あるとき$NULLCMD(catデフォルトでは)、その場合でも、$(<&3)その特別なとして認識されません演算子はksh、ページャーを呼び出して実行する場合と同じように機能します(cat標準出力がパイプになるため、ページャーは同じように動作します)。
しかしながらkshのは、$(< a < b)内容に拡大するa中、zshそれはの内容に展開、aおよびb(または単にb場合はmultiosオプションが無効になっている)、$(< a > b)コピーするaにはb、何も、などに拡大します
bash 演算子は似ていますが、いくつかの違いがあります。
コメントは前では許可されますが、後では許可されません:
echo "$(
# getting the content of file
< file)"
動作しますが:
echo "$(< file
# getting the content of file
)"
何にも拡張されません。
以下のようzshに何のフォールバックはありませんが、一つだけのファイルSTDINリダイレクト、$READNULLCMDので$(<&3)、$(< a < b)リダイレクトを行うが、何にも拡大します。
- 何らかの理由で、
bashは呼び出されませんがcat、パイプを介してファイルのコンテンツを供給するプロセスを引き続きフォークし、他のシェルよりも最適化がはるかに少なくなります。これは、$(cat < file)where catが組み込みのように機能しcatます。
- 上記の結果として、その後で行われた変更はすべて失われます(
$(<${file=foo.txt})たとえば、上記では、その$file割り当ては後で失われます)。
ではbash、IFS= read -rd '' var < file (でも機能しますzsh)は、テキストファイルの内容を変数に読み込むより効果的な方法です。また、末尾の改行文字を保持するという利点もあります。参照してください$mapfile[file]にzsh(でzsh/mapfileもバイナリファイルで動作しているモジュールとのみ、通常のファイルの場合)。
のpdkshベースのバリアントにkshは、ksh93と比較していくつかのバリエーションがあることに注意してください。興味深いことに、mksh(これらのpdkshから派生したシェルの1つ)で、
var=$(<<'EOF'
That's multi-line
test with *all* sorts of "special"
characters
EOF
)
ヒアドキュメントのコンテンツ(末尾の文字なし)が一時ファイルやパイプを使用せずに展開され、他の場合のようにヒアドキュメントの場合と同様に最適化され、効果的な複数行引用構文になります。
およびのすべてのバージョンに移植できるようにするにはksh、コメントの回避のみに制限し、内部で行われた変数への変更が保持される場合と保持されない場合があることに留意してください。zshbash$(<file)
bashは次のように解釈されます」と言ったときcat filename、この動作はコマンド置換に固有のものであることを意味しますか?私が一人で走っ< filenameたとしても、bashはそれを逃がさないからです。何も出力せず、プロンプトに戻ります。