プロセスオーバーライドを使用せずにマルチ出力パイプなどのタスクを実行するためにこれを使用するいくつかの質問があります。
このために固定fd番号を使用するのは安全ですか?プログラムがすでに説明したようにそれを使用している可能性はありますか?ここ重要な内容を扱うのか、それとも関連のない内容を読むのか?
ベストアンサー1
プログラムですでに使用している可能性はありますか?
習慣。プログラムまたはスクリプトが開始される前にI / Oリダイレクトが発生します。
通常、プログラムまたはスクリプトが起動すると、標準記述子(0/標準入力、1/標準出力、2/標準エラー)のみが開きます。 (ターミナル、デバイス、ファイル、またはネットワークソケットを参照できますが、開いている必要があります。1つを「閉じる」の代わりに不要な記述子を/から/dev/null
、本質的に「Nowhere」/「Nothing」にリダイレクトします。)
open
プログラムは、フリーディスクリプタと同様に、システムコールを介してディスクリプタを使用します。つまり、ファイルやソケットを開くときにカーネルは必要ありません。特定の記述子に、カーネル選択記述子。したがって、プログラムが追加の記述子を使用する唯一の時間は、プログラムの開始時に開かれると予想される時間です。このようなまれなユーティリティデーモンがあります。標準記述子に加えて、記述子3が起動時に開かれている場合は、管理サービス(または同様のもの)に接続することを期待しています。
プログラムがハードコーディングされた記述子を使用することを決定した場合(唯一の理由は、他のプログラムをフォークして実行するためです)予想する記述子は開かなければなりません。私が言ったように、これは非常にまれです。すでに開いている記述子は、プログラムがその目的に代わると閉じられます。 (しかし、プログラムがPOSIXyシステムなどの特定の記述子を使用しようとしていることを示すとき、カーネルはシャットダウンを実行します。dup2()
プロセスは気にする必要はありません。)
シェルスクリプト(Bashとsh)は固定記述子番号を使用するため、スクリプトは特定の入力/出力リダイレクトを実行するために特定の記述子を使用できます。しかし、これが起こると、スクリプトは記述子が閉じられていると仮定するため、以前のリダイレクトは無視され、効果はありません。 (説明者が開いていて、スクリプトが一部の内部エントリに対応する記述子を使用している場合、スクリプトがそれをリダイレクトすると、元の記述子は先の段落で述べた理由でカーネルによって最初に閉じられます。で書く必要があります。テスト記述子はすでに開いています避けるリダイレクトしてください。 )
さらに、Fortran I / Oデバイスまたはチャネルは両方とも数字で識別されても記述子とは関係ありません。したがって、Fortranプログラムがユニット10を使用してもディスクリプタ10を使用するという意味ではありません。
このために固定fd番号を使用するのは安全ですか?
はい。 POSIXは、プログラムが少なくとも20の記述子を開くことを指定するので、3から19の間の固定数字はすべてうまく機能します。
重要なのは、これをよく文書化することです。可能であれば、スクリプトの先頭(スクリプトの場合)に簡単な説明を置くか、使用法(-h
または--help
コマンドラインオプション)とマニュアルページ(プログラムの場合)に書き込むことをお勧めします。
スクリプトの場合、競合が発生すると(この場合、上記のように「プログラムが開始されるとすぐにパイプが閉じられるため、スクリプトはまったく機能しません」)、ユーザーは固定記述子番号を変更できると想定できます。彼らのニーズをよりよく満たすために。したがって、スクリプト作成者としてのあなたの使命は、事前に計画を立て、次の人がより簡単に計画できるようにすることです。 (意図と全体的なデザインを説明する明確な説明で十分です。記述子番号を変数に設定したり、スクリプトが実行するすべての小さな操作を説明する必要はありません。)
プログラムがランタイム設定を可能にするのは良い考えです。たとえば、グラフィカルユーザーインターフェースを備えた特別な制御プロトコルに対してプログラム/デーモンに記述子3(オンの場合)を使用させることができます。ただし、特定のコマンドラインオプション(「-c 5」など)では、名前付き記述子文字を使用します。 (または-c /dev/name
指定されたファイル、名前付きパイプ、またはローカルドメインソケットを使用または-c named-pipe
使用)-c :socketpath
この方法では、ユーザーはスクリプトとの競合を簡単に解決できます。