web-dev-qa-db-ja.com

デタッチされたプロセスにターミナルを接続するにはどうすればよいですか?

次のように、端末からプロセスを切り離しました。

$ process &

そのターミナルは長い間閉じられていますが、processはまだ実行中です。そのプロセスのstdinにいくつかのコマンドを送信します。それは可能ですか?

107
Rogach

はい、そうです。最初に、パイプを作成します:_mkfifo /tmp/fifo_。 gdbを使用してプロセスにアタッチします:_gdb -p PID_

次にstdinを閉じます:call close (0);もう一度開きます:call open ("/tmp/fifo", 0600)

最後に、(gdbがハングする可能性があるため、別の端末から)書き込みます。

_echo blah > /tmp/fifo_

117

元の端末にアクセスできなくなった場合...

reptyrはあなたが望むものかもしれません、参照 https://serverfault.com/a/284795/187998

そこからの引用:

まさにそれを行う reptyr を見てください。 githubページにはすべての情報があります。

reptyr-プログラムを「再結合」するためのツール。

reptyrは、既存の実行中のプログラムを取得して新しい端末に接続するためのユーティリティです。 sshを介して実行時間の長いプロセスを開始しましたが、終了する必要があり、中断したくないですか?画面を開始し、reptyrを使用してそれを取得し、sshセッションを終了して家に向かいます。

使用法

reptyr PID

「reptyr PID」は、ID PIDのプロセスを取得し、現在の端末にアタッチします。

接続後、プロセスは^ Cおよび^ Zを含む新しいターミナルからの入力を受け取り、出力を新しいターミナルに書き込みます。 (残念ながら、バックグラウンドで使用している場合でも、古いターミナルで「bg」または「fg」を実行する必要があります。これは、シェルにパッチを適用せずに適切な方法で修正することはおそらく不可能です。)

34
NiKiZe

私はあなたがそれができないと確信しています。

ps xを使用して確認します。プロセスに?controlting ttyとして含まれている場合、それ以上入力を送信することはできません。

9942 ?        S      0:00 tail -F /var/log/messages
9947 pts/1    S      0:00 tail -F /var/log/messages

この例では、9947に入力を送信して、echo "test" > /dev/pts/1などを実行できます。他のプロセス(9942)に到達できません。

次回は、この状況を回避するために screen または tmux を使用できます。

12
andcoz

[〜#〜] edit [〜#〜]:ステファンギメネスが言ったように、それほど単純ではありません。それはあなたが別の端末に印刷することを許可しているだけです。

/ procを使用して、このプロセスへの書き込みを試みることができます。それは/ proc /pid/ fd/0にあるはずなので、単純です:

echo "hello" > /proc/PID/fd/0

それを行う必要があります。私は試していませんが、このプロセスに有効なstdinファイル記述子がある限り、動作するはずです。 / proc /pid/ fd /ls -lで確認できます。

  • / dev/nullへのリンクの場合=>閉じている
  • / dev/pts/Xへのリンクまたはソケットの場合=>開いている

プロセスを実行し続ける方法の詳細については、 Nohup を参照してください。

6
Coren

コマンドラインを&で終了するだけでは、プロセスは完全には切り離されず、バックグラウンドで実行されるだけです。 (zshを使用すると、&!を使用して実際に切り離すことができます。それ以外の場合は、後でdisownを実行する必要があります)。

プロセスがバックグラウンドで実行されると、制御端末からの入力を受け取りません。しかし、fgを使用してフォアグラウンドに送り返すことができます。その後、入力を再度読み取ります。

そうでない場合、ファイル記述子(stdinを含む)を外部から変更したり、失われた制御端末を再接続したりすることはできません。デバッグツールを使用しない限り( Ansgarの回答 または、rettyコマンドをご覧ください)。

5