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


98

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

$ process &

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



1
搜索rettyneercs等,并且还看到serverfault.com/questions/24425serverfault.com/questions/115998
吉尔斯

Answers:


112

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

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

最后,注销(从另一个终端,因为gdb可能会挂起):

echo blah > /tmp/fifo


6
非常令人印象深刻!
塞缪尔·埃德温·沃德

1
我可以做一些类似的事情来将标准输出重定向到文件吗?
rustyx 2014年

@rustyx:未经测试,但这应该可以工作:创建文件而不是管道touch /tmp/thefile。Stdout为1,因此call close (1);另外,请使用正确的写入权限:call open ("/tmp/thefile", 0400)。的echo…,当然,没有必要的。
Ansgar Esztermann 2014年

这很棒!我正在使用它向已完全分离的某些进程发送“ y”或“ n”响应。分离的进程的标准输出到单独的窗口。但是,当我执行此技巧时,我可以看到它在回显它时不会立即“接收”“ y”或“ n”,因此我必须退出gdb并分离它,然后它会相应地接收所有回显,因此有没有一种方法可以执行此过程而无需从进程接收到来自fifo的输入之前退出gdb?
krb686

不幸的是,它似乎一直挂着call open("/tmp/fifo", 0600)。任何帮助将不胜感激
弓箭手

27

当原始终端不再可用时...

reptyr可能就是您想要的,请参阅https://serverfault.com/a/284795/187998

从那里引用:

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

reptyr-用于“重探”程序的工具。

reptyr是用于获取现有正在运行的程序并将其附加到新终端的实用程序。在ssh上启动了一个长期运行的进程,但是不得不离开并且不想中断它吗?只需启动一个屏幕,使用reptyr抓取它,然后终止ssh会话并返回首页即可。

用法

复数PID

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

附加后,该过程将从新终端接收输入并将输出写入新终端,包括^ C和^ Z。(不幸的是,如果您将其作为背景,您仍然必须在旧终端中运行“ bg”或“ fg”。如果不修补外壳,可能无法以合理的方式进行修复。)


12

我很确定你不能。

使用检查ps x。如果某个进程具有?作为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/19942无法达到其他过程()。

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


5
或者,dtach如果您不需要整体screen
manatwork'2

4
有一个在标准(POSIX,SUS)没办法,但在许多(大多数?)系统它使用调试器使用的机制成为可能。请参阅Ansgar的答案。随着root你甚至可以这样对其他用户的进程。
dmckee 2012年

3
这样做echo "test" > /dev/pts/1不会将输入发送到流程9947-它将在该流程的终端上输出单词“ test”。
psmears 2014年

6

编辑:正如斯蒂芬·吉梅内斯所说,这不是那么简单。它只允许您打印到其他终端。

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

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

应该这样做。我没有尝试过,但是只要该过程仍然具有有效的stdin文件描述符,它就可以工作。您可以ls -l/ proc / pid / fd /上进行检查

  • 如果是到/ dev / null的链接=>则关闭
  • 如果是到/ dev / pts / X的链接或套接字=>则打开

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


2
没那么简单。例如,如果stdin链接到终端,则echo向终端设备显示内容只会打印您在终端上写的内容,而不会将其传输到进程中。
斯特凡希门尼斯

5

&仅以命令行结尾将不会完全分离该进程,它将仅在后台运行。(zsh可以使用&!它来实际分离它,否则可以disown稍后再使用)。

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

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


而且还有一个相关的问题在这里:unix.stackexchange.com/q/17648/9426
斯特凡希门尼斯

@Rogach指出“该终端现已长期关闭”。
andcoz

1
@andcoz:是的,但他很幸运,该程序尚未通过SIGHUPed处理。我在建议一种更安全的方法。
斯特凡希门尼斯

在这里,只有断绝关系真正起作用的,如果我第一次将stdout像>>/dev/stderr,否则,当我关闭终端,将“六亲不认”的过程将结束太..我从来没有真正理解这个寿..
水瓶座电
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.