今日、私はこの記事でfifoについて何かを学んでいます: cat <(ls -l)
に言及する名前付きパイプの紹介 。
エラーを表示するsort < (ls -l)
を使用していくつかの実験を行いました。
-bash: syntax error near unexpected token `('`
その後、コマンドに余分なスペースを誤って追加したことがわかりました。
しかし、なぜこの余分なコマンドがこの失敗につながるのでしょうか?リダイレクトシンボルを(
の近くに配置する必要があるのはなぜですか?
これは_<
_ではないため、完全に異なる<()
です。これは プロセス置換 と呼ばれ、あるプロセスの出力を別のプロセスの入力として使用できるようにする特定のシェルの機能です。
_>
_および_<
_演算子は、filesへの入力および(== --- ==)ファイルからの入力をリダイレクトします。 <()
演算子は、ファイルではなくコマンド(プロセス)を扱います。あなたが走るとき
_sort < (ls)
_
コマンドls
をサブシェルで実行しようとしています(かっこはその意味です)、そのサブシェルを入力ファイルとしてsort
に渡そうとしています。ただし、これは受け入れられない構文であり、見たエラーが発生します。
それが意図されている方法だからです。
bash
の<(...)
は、プロセス置換の構文です。 ksh
の同じ演算子からコピーされます。
_<
_、_(
_、_)
_、_|
_、_&
_、_;
_はbash
の特別な字句トークンで、特殊な演算子をさまざまな組み合わせで形成します。 _<
_、_<(
_、_<<
_、_<&
_...それぞれに役割があります。 _<
_はリダイレクト用です。 _<file
_、_< file
_は、ファイルから入力をリダイレクトします。 <'(file)'
は、_(file)
_というファイルから入力をリダイレクトしますが、<(file)
は、リダイレクト演算子ではない別の演算子です。
< (file)
は_<
_の後に_(file)
_が続きます。そのコンテキストでは、bash
では、_(file)
_は無効です。 _(...)
_は、次のような一部のコンテキストでは単一のトークンとして有効です。
_(sub Shell)
func () {
...
}
var=(foo bar)
_
しかしではない
_sort < (cmd)
_
fish
シェルでは異なります。 fish
では、_(...)
_はコマンド置換用です(bash
の$(...)
に相当)。また、_<
_は、Bourneのようなシェルのような入力リダイレクト用です。
したがって、fish
には:
_sort <(echo file)
_
次と同じになります:
_sort < (echo file)
_
あれは:
_sort < file
_
しかし、それはbash
のプロセス置換とはまったく異なるものです。
yash
シェル、別のPOSIXシェルでは、<(...)
はプロセス置換ではなく、プロセスリダイレクトです。
そこで、
_sort <(ls -l)
_
の略:
_sort 0<(ls -l)
_
リダイレクト演算子です。それは多かれ少なかれ同等です:
_ls -l | sort
_
bash
では、<(ls -l)
はパイプのパスに展開されるため、次のようになります。
_ls -l | sort /dev/fd/0
_
zsh
では、_(...)
_がグロブ演算子(_(*.txt|*.png)
_はtxt
およびpng
ファイルに展開されます)として、およびグロブ修飾子(*(/)
は、たとえばディレクトリファイルに展開されます)。
zsh
内:
_sort < (ls -l)
_
その_(ls -l)
_はグロブ修飾子として扱われます。 l
glob修飾子はリンクの数で一致し、l
の後に数字を期待します(ls -ld ./*(l2)
は2つのリンクを持つファイルを一覧表示します)。そのため、そこで_zsh: number expected
_エラーが発生します。
_(w)
_が空の名前の書き込み可能なファイルと一致するため、sort < (w)
は代わりにzsh: no matches found: (w)
エラーを返します。
sort < (w|cat)
は、現在のディレクトリにあるw
およびcat
ファイルの内容をソートします...