なぜ `sort <(ls -l)`は機能するのに `sort <(ls -l)`は失敗するのですか?


32

今日、私はこの記事でFIFOについて何かを学んでいる:はじめに名前付きパイプに言及し、cat <(ls -l)

sort < (ls -l)エラーを表示するを使用して、いくつかの実験を行いました。

-bash: syntax error near unexpected token `('`

次に、コマンドに余分なスペースを誤って追加したことがわかりました。

しかし、なぜこの余分なコマンドがこの失敗につながるのでしょうか?リダイレクトシンボルをに近づける必要があるのはなぜ(ですか?


* nixシェルは、Alecが言及したトークンを作成する空白に基づいて物事を分割することに注意してください。

回答:


45

それはでないので<<()これはまったく異なります。これはプロセス置換と呼ばれ、あるプロセスの出力を別のプロセスの入力として使用できる特定のシェルの機能です。

>そして<オペレータは、からにして、入力、出力をリダイレクトするファイル<()オペレータは、ファイルではないコマンド(プロセス)を扱います。走るとき

sort < (ls)

lsサブシェルでコマンドを実行しようとしています(これが括弧の意味です)。次に、そのサブシェルを入力ファイルとしてに渡しますsort。ただし、これは受け入れられない構文であり、見たエラーが発生します。


3
あなたの答えは良いですが、then sort is attempting to read the subshell as its input file→Bashは構文を解析することさえしないので、これは明らかに間違っています。どちらlssort実際には実行されません。
sleblanc

1
@sebleblancフェアポイント、答えを言い換えました、ありがとう。
テルドン

1
この場合、サブシェルはありません。< (ls)ここでは有効なトークンではありません。
クオンルム

@cuonglmいいえ。bashは構文エラーとして扱うためです。私のポイントは、サブシェルで(ls)実行lsされることです。
テルドン

22

それがそうであることを意味するからです。

<(...)in bashはプロセス置換の構文です。の同じ演算子からコピーされkshます。

<()|&;特殊な字句であるbash異なる組み合わせで特殊な演算子を形成するために使用されます。<<(<<<&...それぞれが自分の役割を担っています。<リダイレクト用です。<file< fileファイルから入力をリダイレクトします。<'(file)'と呼ばれるファイルから入力をリダイレクトします(file)<(file)、リダイレクト演算子ではない別の演算子です。

< (file)<続き(file)ます。その意味で、でbash(file)有効ではありません。(...)次のようなコンテキストでは、単一のトークンとして有効になります。

(sub shell)
func () {
  ...
}
var=(foo bar)

しかしではない

sort < (cmd)

ではfish、シェル、それは違います。コマンド置換(のと同等のためですで)。また、Bourneのようなシェルのような入力リダイレクト用です。fish(...)$(...)bash<

だから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)展開される)グロブ修飾子として(たとえば、ディレクトリファイルに展開される)オーバーロードされます。txtpng*(/)

ではzshでは、:

sort < (ls -l)

これ(ls -l)は、glob修飾子として扱われます。lリンクの数に一致することであり、後の数字を期待修飾子グロブl(のようにするとls -ld ./*(l2)、2つのリンクを持つファイルを一覧表示します)ので、あなたが得る理由のzsh: number expected誤差が。

sort < (w)与えられたであろうzsh: no matches found: (w)として代わりにエラーを(w)書き込み可能です、空の名前を持つファイルが一致します。

sort < (w|cat)wおよび/またはcat現在のディレクトリ内のファイルのコンテンツをソートしているでしょう...


sort < $(ls -l)このエラーが発生する理由:bash: $(ls -l): ambiguous redirect
エドワードトーバルズ

@edwardtorvalds $(ls -l)。複数の単語に展開されるため。split + glob(sort < "$(echo file)")を防ぐために引用符を使用します。bashPOSIX sh の動作または動作とは、bashが非対話型(shあたかも呼び出されたときではない)ときにもsplit + globを行うという点で異なることに注意してください。
ステファンシャゼラス

を見るls -l | sort /dev/fd/0と、の出力ls -lはに保存されている/dev/fd/0と言え、sortコマンドはそれを読み取って目的の出力を提供します。tail -f --retry /dev/fd/0そのファイルを監視するために使用していますが、出力が得られません。どうして?どうすればそのファイルを読むことができますか?
エドワードトーバルズ

魚では、(foo | psub)入力プロセスの置換を実現するために使用できます。出力プロセス置換の代替(ha)はまだありません。
ザンチー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.