web-dev-qa-db-ja.com

プロセスの置換により、パイプである/ dev / fd / 63というファイルが生成されるのはなぜですか?

この特定の例のコンテキストで名前付きパイプを理解しようとしています。

端末に<(ls -l)と入力して、出力を_bash: /dev/fd/63: Permission denied_として取得します。

cat <(ls -l)と入力すると、ディレクトリの内容が表示されます。 catechoに置き換えると、端末名が表示されると思います(またはそうですか?)。

echo <(ls -l)は、出力を_/dev/fd/63_として提供します。

また、この出力例は私には不明確です。

_ls -l <(echo "Whatever")
lr-x------ 1 root root 64 Sep 17 13:18 /dev/fd/63 -> pipe:[48078752]
_

ただし、ls -l <()を指定すると、ディレクトリの内容が表示されます。

名前付きパイプの場合はどうなりますか?

42
Ramesh

<(some_command)を実行すると、シェルは括弧内のコマンドを実行し、全体をファイル記述子に置き換えます。ファイル記述子は、コマンドのstdoutに接続されています。したがって、_/dev/fd/63_は、ls呼び出しの出力を含むパイプです。

<(ls -l)を実行すると、_Permission denied_エラーが発生します。これは、行全体がパイプで置き換えられ、実行可能でないコマンドとして_/dev/fd/63_を効果的に呼び出そうとするためです。

2番目の例では、cat <(ls -l)は_cat /dev/fd/63_になります。 catがパラメーターとして指定されたファイルから読み取ると、コンテンツが取得されます。一方、echoは、パラメータを「そのまま」出力します。

最後のケースである<()は、コマンドがないため、単に何にも置き換えられません。しかし、これはシェル間で一貫していません。zshでは、まだパイプが空です(空です)。

概要<(command)を使用すると、通常はファイルが必要なコマンドの出力を使用できます。

Edit:as Gilles が指摘するように、これは名前付きパイプではなく、匿名パイプです。主な違いは、プロセスが実行されている間のみ存在し、名前付きパイプ(たとえば、mkfifoを使用して作成された)は、プロセスがアタッチされていないままになるということです。

38
crater2150