バックグラウンドプロセスのパイプ入力


14

画面に「aaa」を表示する場合:

(1)$: echo aaa | cat                 ... works OK
(2)$: echo aaa | ( cat )             ... works OK
(3)$: echo aaa | ( cat & )           ... NOT working
(4)$: ( echo aaa & ) | cat           ... works OK 
(5)$: echo aaa | ( cat <&0 & )       ... works ok in BASH (but not in SH)
(6)$: echo aaa | ( cat <&3 & ) 3<&0  ... works ok in BASH and SH

(3)と(4)からの結論->切り離されたプロセスには、制御、使用、リダイレクト...できる接続された出力がありますが、入力はできません!

私の質問は、誰かがライン(5)が機能する理由と方法を理解しています

...「<&0」は「0 <&0」の略で、なぜ0から0にリダイレクトするのが解決策であり、実際に分離プロセスの入力で何が起こるのか。サブシェルは問題ではありません。(...)の代わりに中括弧{...}を使用しても同じ結果が得られます。

... and question2:「分離プロセスへの入力を与える」ための行(6)よりも優れたソリューションがあります。

回答:


12

はい、POSIXの要求に応じて、バックグラウンドで開始されたコマンドの&標準入力はからリダイレクトされ/dev/nullます。

本当に

{ cmd <&3 3<&- & } 3<&0

これを回避する最も明白な方法です。

ただし、パイプラインの一部をバックグラウンドで実行する理由は明らかではありません。


理由は、パイプチェーン内の特定の1つのコマンドのPIDを取得することでした(cmd1 | {cmd2&; pid2 = $ !;} | cmd3 ...、したがって/ dev / null ==&0がBGプロセスの標準です。理由もわかりますか「0 <&0」はbashで機能しますが、安全ですか?
Asain Kujovic

3
@OmerMerdan POSIXは、すべての場合において、標準入力の明示的なリダイレクトがこのアクティビティをオーバーライドすることを述べていますが、これは何らかの形で上記のことと矛盾するためbash/dev/nullリダイレクトをキャンセルすると解釈します(合理的な解釈のように聞こえます)。現在、同じことを行うシェルは多くありません。Ashとpdkshはサポートしていません。
ステファンシャゼル

なぜそれが3<&-必要な部分であり、それを使用しても安全ですか?
mvorisek

1
@ Mvorisek、fd 3は一時的に元のstdinを復元するためにのみ使用されます。cmd必要ないので閉じます。fd 0(の<&30<&3)に追加した後、閉じます。
ステファンシャゼル

1
@Mvorisekは、nohupstdinを/ dev / nullにリダイレクトするため、次のものが必要です{ nohup sh -c 'cmd <&3 3<&-' & } 3<&0。または(trap '' HUP; cmd <&3 3<&- > nohup.out 2>&1 &) 3<&0
ステファンシャゼル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.