出力を動的にリダイレクト - Linuxでは不可能なようです。なぜですか?

出力を動的にリダイレクト - Linuxでは不可能なようです。なぜですか?

Web検索を試しましたが、Linuxリダイレクト出力を動的に検索して回答を見つけられませんでした。私が理解したのは、出力にstdoutがファイル記述子1を使用して動作することを示しています。

$ ls -l /proc/pid/fd/1
lrwx------ 1 user1 user1 64 Sep 27 13:37 1 -> /dev/pts/1

これには、ファイルに書き込んで読み取ることができるprocファイルシステムで動作するいくつかのUnixコマンドがあります。たとえば、Linuxの場合、ユーザーがこれらのリンクを手動で変更できる実装がないのはなぜですか? (しようとするとエラーが発生します。)実装するのは難しいですか?ユーティリティプログラマはどのユーティリティを使用すべきかをどのように決定しますか?lsteecatln -sbash"No such file or directory"proc

答え1

Linuxなどのシステムでは、ユーザーがbashでln -sを介してこれらのリンクを手動で変更できるのはなぜですか?

procファイルシステムは内部カーネル状態のみを表示するためです。場合によっては、特定のファイルにコンテンツを作成して実際にカーネルの状態に影響を与える可能性がありますが、コンテンツを移動できる例は考えられません。

実装するのは難しいですか?

カーネルはオープンソースなので、直接見て決定することができます(「難しさ」はプログラミングの経験によって異なります)。

また、変更中のプロセスが標準出力に書き込まれる場合に何が起こるのかを考えてください。考慮すべきセキュリティ関連事項もあります。

しかし、私の考えでは、上流のカーネルがそのような修正を受ける可能性はおそらく非常に低いでしょう。

ユーティリティプログラマは、procにどのユーティリティを使用すべきかをどのように決定しますか?

/proc仮想ファイルシステムなので、仮想ファイルシステムに必要なカーネル機能を実装します。すべての種類のカーネルプログラマは通常、カーネルを使用するときに/proc最小限の労働集約的な方法でプログラムしようとします。

答え2

Linux では、標準入出力ファイル記述子が/procファイルシステムではなくカーネルシステムコールによって生成されます。

表示されるシンボリックリンク/procは、データをパイピングするための実際の手段ではありません。反射プロセスがデータにアクセスできるようにカーネルが実行するアクション。そのためln -s変更できません。

出力を動的にリダイレクトする方法に関する質問に関して、これを行うことができるコマンドがわかりません。しかし、それは確かに可能です。以下は、そのようなプログラムを開発する方法の例です。

  1. まず、実装された機能から始めますcat。したがって、標準入力を受け取り、標準出力にダンプします。これは非対話型アプリケーションになります。
  2. 次に、プログラムをインタラクティブに変更します。簡単な例は、少量の入力を送信し、ユーザーがENTERキーを押すのを待つことです。その後、もう少し入力を移動して繰り返します。この段階では、プログラムは一時停止して決定を下すことができ、これは出力を動的にリダイレクトするために重要です。
  3. 最後に、入力と出力を指定するコマンドを受け入れるようにプログラムを変更します。 API、NCURSES UIなどを備えたデーモンかもしれません。

上記はもちろん言葉のように簡単ではありません。重要な詳細はたくさんありましたが、これは少なくとも出力を動的にリダイレクトすることが可能であることを示すのに十分だと思います。

答え3

stdinなどが指す場所を変更する代わりに、1つを作成できます。擬似端末(PTY)プログラムが変更されたことを知る必要がないように、入力と出力をリダイレクトします。実際にこれを行ういくつかのプログラムがあります(しばしばターミナルマルチプレクサ.)

ご存知のように、ある端末のセッションを切断したりなどのマルチプレクサを使用して他の場所から再接続できますが、tmux常に標準入力または出力をパイプすることもできます。たとえば、tmuxウィンドウ内で実行されているシェルがあり、コマンドを送信した場合pipe-pane 'cat >>~/test.txt'(次から取得)マニュアルページ)セッションウィンドウ内で何も変更せずにtmux標準出力を追加します。~/test.txt

答え4

ここで重要な誤解は、シンボリックリンクの作成中に変更すると、予想される方法ですべてが変更されることです。

しないでしょう。物理ファイル(またはデバイスまたはパイプ)が開かれると、すべてのアクティビティは開かれたファイルに基づいており、それを指すシンボリックリンクなどのすべての操作は無視されます。実際、これはシンボリックリンクに限定されず、ファイルに名前を付ける「ハード」リンクにも同じことが当てはまります。 Unixシステムでは、実際にファイルを移動または削除(!)することもできます(上書きの代わりに!)。何かプロセスが開いていてファイルが閉じられるまで、プロセスに変更は表示されません。

関連情報