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

$ process &


该终端现在已经长时间关闭,但是process仍在运行,我想向其中发送一些命令这个过程是标准输入。有可能吗?

评论

如何取消它正在运行的进程并将其关联到新的屏幕外壳的可能副本?

搜索retty,neercs等,另请参阅serverfault.com/questions/24425、serverfault.com/questions/115998

#1 楼

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

,然后关闭stdin:call close (0);然后再次打开它:call open ("/tmp/fifo", 0600)

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

echo blah > /tmp/fifo

评论


非常令人印象深刻!

–塞缪尔·埃德温·沃德(Samuel Edwin Ward)
2012年2月16日在18:59

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

–rustyx
14年8月25日在15:28

@rustyx:未经测试,但这应该起作用:创建文件而不是管道,请触摸/ tmp / thefile。标准输出为1,因此调用close(1);另外,使用正确的写入权限:调用open(“ / tmp / thefile”,0400)。当然,不需要回声。

– Ansgar Esztermann
14年8月26日在11:25

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

–krb686
15年7月27日在13:50

不幸的是,它似乎挂在通话open(“ / tmp / fifo”,0600)上。任何帮助将不胜感激

–archer
18/12/22在13:34

#2 楼

如果原始终端不再可用...

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

从那里报价:

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


reptyr-用于“重新侦听”程序的工具。

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

使用方法

reptyr PID

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

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




评论


如果尚未安装,请尝试sudo yum install -y reptyr。这对于我接管SSH连接断开时丢失的vi编辑会话非常有用(只需将^ L移回以查看我的所有更改并继续编辑后,只需按^ L即可)。

–加里
20年1月29日在1:29

我没有安装此程序,也无法使用包管理器,因为断开连接的进程是dpkg。我下载了deb(pkgs.org/download/reptyr),做了dpkg-deb --extract reptyr_0.6.2-1.2_amd64.deb reptyr && reptyr / usr / bin / reptyr $ PID_OF_WANTED_PROCESS

– miigotu
20-4-3在5:59



基本上与@miigotu相同:从pkgs.org/download/reptyr下载(我希望是)正确的软件包并提取reptyr ...能够保存来自分离的VI会话的文件。

– TripeHound
20年4月13日在12:57

#3 楼

我很确定您不能。

使用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/1。其他过程(9942)无法实现。

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

评论


如果不需要整个屏幕,请分开。

–manatwork
2012年2月16日13:32

标准中没有办法(POSIX,SUS),但是在许多(大多数?)系统上,可以使用调试器使用的机制。请参阅Ansgar的答案。使用root,您甚至可以对其他用户的进程执行此操作。

– dmckee ---前主持人小猫
2012年2月16日在21:30



执行echo“ test”> / dev / pts / 1不会将输入发送到进程9947-它会在该进程的终端上输出单词“ test”。

–psmears
2014年11月20日在22:59

#4 楼

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

您可以尝试使用/ proc写入此过程。它应该位于/ proc / pid / fd / 0中,因此应该执行一个简单的:

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


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


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

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

评论


没那么简单。例如,如果stdin链接到终端,则在终端设备上回显某些内容只会打印您在终端上写的内容,而不会将其传输到进程中。

–StéphaneGimenez
2012年2月16日在16:16

#5 楼

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

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

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

评论


这里有一个相关的问题:unix.stackexchange.com/q/17648/9426

–StéphaneGimenez
2012年2月16日在16:04

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

– andcoz
2012年2月16日在18:35

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

–StéphaneGimenez
2012-2-17在11:25

在这里,只有当我首先使用>> / dev / stderr重定向stdout时,disown才真正起作用,否则,当我关闭终端时,“ dissigned”过程也将结束..我从来没有真正理解过。

–水瓶座力量
2015年11月20日下午5:08