リダイレクトおよび/またはパイプを含む組み込みコマンドの動作のPOSIX仕様は何ですか?

リダイレクトおよび/またはパイプを含む組み込みコマンドの動作のPOSIX仕様は何ですか?

次のコマンドを検討してください。

exit > /dev/null
exit | cat

一部のシェル(ksh、bash、(d)ash)では、動作は同じです。最初のコマンドを実行すると、シェルはすぐに終了しますが、2番目のコマンドには目立つ動作はありません。

exit私は最初のコマンドがfork(2)を含まないのに対して、2番目のコマンドは2つ(1つはexec用、もう1つはexecve(2)用)に関連しているという結論に達しましたcat

POSIX仕様のセクション2.14を見てみましたが、それを明示的に説明する項目が見つかりませんでした。

POSIXでは、一部のコマンドはfork(2)を実行しないでくださいが、他のコマンドは必ず実行する必要があると指定していますか?最初のコマンドのサブシェルを作成することは標準に従って許可されていますか?


( exit )角かっこはexit実際にコマンドを実行するサブシェルを生成するので、現在シェルを終了してはいけないことを知っています。つまり、サブシェルがすぐに終了することを意味します。しかし、ここには角かっこがないので、リダイレクトとパイプについてはよくわかりません。

私がこの質問をしたのは、最近のコースの練習で最小限のUnixシェルを実装するように指示されたからです。これを補うために実装できる「オプションの機能」がたくさんあります。これらの「オプションの機能」の1つは、リダイレクトとパイプの組み合わせです。私たちはいくつかの異なる実装を持っており、そのうちのいくつかは他のものよりもPO​​SIXの指定された動作に近いと思うので、実際の動作がどのように指定されるかを知りたいと思います。

ベストアンサー1

素晴らしい(出口)、

これ出口ユーティリティはシェルを有効にする必要があります。やめる 現在の実行環境[...]

そして(2.12。シェル実行環境)

サブシェル環境は、シェル環境のコピーとして作成する必要があります。 [...] さらに、各コマンドについて サブシェル環境にあるマルチコマンドパイプライン;ただし、拡張機能を使用すると、パイプラインの一部またはすべてのコマンドを現在の環境で実行できます。他のすべてのコマンドは 現在のシェル環境

したがってexit、パイプラインの内容は独自の実行環境/サブシェルで実行および終了しますが、単純なコマンドの内容はデフォルトのシェルexit > /dev/null環境で実行されます。 (コメントで指摘したように、リダイレクトは実際にはまったく影響しません。)

2番目の引用符の間の部分は、一部のシェルがデフォルト環境にパイプされたすべてのコマンドを実行できることを意味するため、この場合でもシェル全体が終了します。実際には、パイプラインの最後のコマンドに対してこれを行うのがより一般的です。

たとえば、Bashではlastpipe次のようになります。

$ bash -c 'true | exit; echo end.'
end.

しかし、

$ bash -O lastpipe -c 'true | exit; echo end.'

何も印刷されません。

おすすめ記事