如何将终端附加到分离的进程?

Rog*_*ach 128 linux command-line shell process terminal

我已经从我的终端分离了一个进程,如下所示:

$ process &
Run Code Online (Sandbox Code Playgroud)

该终端现已长期关闭,但process仍在运行,我想向该进程的标准输入发送一些命令。那可能吗?

Ans*_*ann 131

是的。首先,创建一个管道: mkfifo /tmp/fifo. 使用 gdb 附加到进程: gdb -p PID

然后关闭标准输入:call close (0); 并再次打开它:call open ("/tmp/fifo", 0600)

最后,写下(从不同的终端,因为 gdb 可能会挂起):

echo blah > /tmp/fifo

  • 非常令人印象深刻! (7认同)
  • 这仍然有效吗?不幸的是对我不起作用(ubuntu 18) (2认同)

NiK*_*iZe 46

当无法再访问原始终端时...

reptyr可能是你想要的,见https://serverfault.com/a/284795/187998

从那里引用:

看看reptyr,它就是这样做的。github 页面包含所有信息。

reptyr - 一种用于“重新制作”程序的工具。

reptyr 是一个实用程序,用于获取现有正在运行的程序并将其附加到新终端。通过 ssh 启动了一个长时间运行的进程,但必须离开并且不想中断它?只需启动一个屏幕,使用 reptyr 抓取它,然后终止 ssh 会话并回家。

用法

爬虫PID

“reptyr PID”将获取 id PID 的进程并将其附加到您当前的终端。

附加后,该进程将从新终端获取输入并将输出写入新终端,包括 ^C 和 ^Z。(不幸的是,如果您将其作为后台处理,您仍然需要在旧终端中运行“bg”或“fg”。如果不修补您的 shell,这可能无法以合理的方式修复。)

编辑声称“reptyr无法获取具有子进程的进程。或者子进程(reptyr 版本 0.6.2)。” 有限的支持确实存在问题问题

  • 我没有安装这个,并且无法使用包管理器,因为我断开连接的进程是 dpkg。我下载了deb(https://pkgs.org/download/reptyr),做了一个`dpkg-deb --extract reptyr_0.6.2-1.2_amd64.deb reptyr && reptyr/usr/bin/reptyr $PID_OF_WANTED_PROCESS` (3认同)

and*_*coz 13

我很确定你不能。

检查使用ps x. 如果一个进程有一个?作为控制的 tty,你就不能再向它发送输入。

9942 ?        S      0:00 tail -F /var/log/messages
9947 pts/1    S      0:00 tail -F /var/log/messages
Run Code Online (Sandbox Code Playgroud)

在这个例子中,你可以发送输入9947来做类似的事情echo "test" > /dev/pts/1。另一个进程 ( 9942) 不可访问。

下次,您可以使用screentmux来避免这种情况。

  • 或者 [`dtach`](http://dtach.sourceforge.net/) 如果你不需要整个 `screen`。 (5认同)
  • 标准(POSIX,SUS)没有办法,但在许多(大多数?)系统上,它*是*可能使用调试器使用的机制。参见 [Ansgar 的回答](http://unix.stackexchange.com/a/31830/3270)。使用 `root` 你甚至可以对其他用户的进程执行此操作。 (4认同)
  • 执行 `echo "test" > /dev/pts/1` 不会将输入发送到进程 `9947` - 它会在该进程的终端上输出单词“test”。 (3认同)

Sté*_*nez 8

只是结束命令行&不会完全分离进程,它只会在后台运行它。(zsh你可以用&!它来实际分离它,否则你以后再做disown)。

当一个进程在后台运行时,它将不再接收来自其控制终端的输入。但是您可以将它发送回前台,fg然后它会再次读取输入。

否则,不可能从外部更改其文件描述符(包括标准输入)或重新连接丢失的控制终端……除非您使用调试工具(请参阅Ansgar 的回答,或查看retty命令)。


Cor*_*ren 7

编辑:正如 Stephane Gimenez 所说,事情没那么简单。它只允许您打印到不同的终端。

您可以尝试使用/proc写入此进程。它应该位于/proc/ pid /fd/0,所以很简单:

echo "hello" > /proc/PID/fd/0
Run Code Online (Sandbox Code Playgroud)

应该这样做。我还没有尝试过,但它应该可以工作,只要这个进程仍然有一个有效的标准输入文件描述符。您可以ls -l/proc/ pid /fd/上检查它。

  • 如果它是 /dev/null 的链接 => 它已关闭
  • 如果它是指向 /dev/pts/X 或套接字的链接 => 它是打开的

有关如何保持进程运行的更多详细信息,请参阅nohup

  • 没那么简单。例如,如果 stdin 链接到终端,则向终端设备“回显”某些内容只会打印您在终端上写的内容,而不会传输到进程。 (2认同)