我在SSH Shell上有一个正在运行的程序。我想暂停它,并在返回时能够取消暂停它的执行。

我想到的一种方法是将其所有权转移到屏幕外壳,从而使其在其中运行。

还有其他方法吗?

评论

另请参阅是否可以对已启动的进程进行nohup /筛选?和Resume命令在已删除的SSH会话中运行,其中提到了(目前)此处未提及的几种基于ptrace的解决方案。

从诸如unix.stackexchange.com/a/4039/13496之类的问题中,我听到了有关retty和neercs的信息。嗯...想知道在下次运行进程之前是否有像“ screen here”这样的层,将来是否应该失去顶级终端,这将使您很容易恢复到stdin / out / err

我不能理解的这个问题中的次要/隐性问题是...为什么在后台有一个更新的/刚刚发布的甚至不需要/等待stdin的情况下,shell为什么选择放弃暂挂的工作?这是我已经习惯的治疗方法,所以不知道这里发生了什么...

#1 楼

您可以使用内置的disown从外壳撤消程序的“所有权”:

# press Ctrl+Z to suspend the program
bg
disown


但是,这仅告诉外壳程序不向其发送SIGHUP信号。外壳退出时执行程序。程序将保留与终端的任何连接,通常作为标准输入,输出和错误流。无法将它们重新连接到另一个终端。 (屏幕通过模拟每个窗口的终端来工作,因此程序会附加到屏幕窗口。)通过将程序附加到Windows中,可以将文件描述符重新附加到其他文件。调试器(即使用ptrace)并将其称为opendupclose。有一些工具可以做到这一点。这是一个棘手的过程,有时它们会使该过程崩溃。可能的情况包括(从答案中收集的链接,以至我如何放弃正在运行的进程并将其关联到新的屏幕外壳?以及我是否可以对已启动的进程进行nohup /筛选?):



抓取(以及更具野心的cryopid)
neercs
重定向
reptyr
retty


评论


disown从工作控制列表中删除该过程。

–ctrl-alt-delor
2015年4月15日14:39



为什么不放弃-h?

– Cees Timmerman
15年6月17日在15:18

@CeesTimmerman将工作留在shell的工作表中,但是这样做的好处是什么?

–吉尔斯'所以-不再是邪恶的'
15年6月17日在15:20

@吉尔斯:所以您仍然可以fg或杀死它,看看它是否自行结束。

– Peter Cordes
15年8月11日在20:47

提到的实用程序可用于一组进程(例如bzcat a.bz2 | grep文本)? Man for reptyr说,它不支持将过程与孩子一起移动。

– dma_k
2015年10月18日在9:17

#2 楼

最好使用GNU screen

第一次登录时开始运行屏幕-我运行screen -D -R,运行您的命令,并用CTRL-Z断开或挂起它,然后先按CTRL-A再按D与屏幕断开连接。

再次登录计算机时,请运行screen -D -R重新连接。您将和以前一样在同一外壳中。您可以运行jobs来查看挂起的进程(如果已执行),然后运行%1(或相应的作业号)再次使其处于前台。

评论


我认为这不能回答问题。问题开始于“我正在运行程序”。该答案假设它尚未运行…

– Anko
15年4月16日在9:25



是的,他清楚地写了他想让它进入屏幕讨论的过程:-)

–弗洛里安·海格尔(Florian Heigl)
19-10-8在17:12

这不能回答问题,或者至少不能回答被链接的问题:unix.stackexchange.com/questions/171250/…

–user3728501
20年6月11日在19:26

#3 楼

要在终端之间移动流程或重新连接不使用的商品,您可以使用例如reptyr。

评论


是的,保存了它,谢谢!我在作者的网站上读到了它比类似或更旧的工具更好的工作方式。对于ncurses程序。

– Marcos
2012年3月8日15:19

这太棒了;它应该解决朋友经常通过ssh直接运行它然后需要上火车而失去工作的困境。 “糟糕,忘记使用屏幕了。再次。”

–亚当·卡兹(Adam Katz)
15年1月16日在5:13

+1尽管接受的屏幕答案当然是理想的,但实际上并不能回答问题,它特别要求一种将当前正在运行的进程移至屏幕等的方法。另请参阅以下答案:serverfault.com/a/284795

–毒素
2015年4月18日在21:15

绝对的救星。让我重新连接到正在等待用户确认的apt dist-upgrade上。

– andig
19年2月10日在12:24

可以在基于Debian的发行版上使用APT安装:sudo apt install reptyr。

–木材
20年7月9日在10:46

#4 楼

我最喜欢的解决方案是使用tmux,您可以分离会话,然后将其重新连接到另一个终端。

从上一个会话分离时,可以安全地关闭终端;以后,即使您已注销,也可以使用tmux attach返回会话。

评论


您还可以与您的朋友分享会话,并使用多个窗口和窗格等等!喜欢它^ _ ^

–igor
13年9月24日在8:03

使用示例?

– Vitaly Zdanevich
16年2月20日,0:55

#5 楼

还有一个名为retty的小实用程序,可让您将正在运行的程序重新连接到另一个终端。

#6 楼

我不经常使用它,但是neercs声称支持这一点。这是一个类似于screen的程序,具有多种高级功能,例如更好的窗格管理,但它提供的主要功能是能够将进程导入到窗格中

评论


有趣。它的确发挥作用(ptrace),但它不仅操纵文件描述符,而且还分叉了该过程。它可以抓取find /,但是使交互式bash崩溃了。

–吉尔斯'所以-不再是邪恶的'
2010-11-13 22:20

@Gilles我不记得尝试时的情况,但声誉不佳,有人告诉我它经常失败

– Michael Mrozek
2010-11-13 22:25

#7 楼

如果只想暂停并随后重新启动,可以将killSTOPCONT信号一起使用。

首先找出带有

$ ps aux

的PID的过程
然后将信号发送到进程中列出的那个PID

$ kill -STOP <PID>

$ kill -CONT <PID>


#8 楼

ThomasHabets的“ injcode”似乎正是我需要的东西:

https://github.com/ThomasHabets/injcode

injcode程序允许注入任意代码进入正在运行的
进程,无论您是否事先知道并正在运行屏幕或tmux

从README:


示例1:移动irssi从一个终端到另一个终端

也许将其移到屏幕中。

首先在一个终端中启动irssi。

在另一个终端中运行injcode:
$ injcode -m retty

Irssi现在应该移动到第二个终端,包括拥有一个新的
控制终端。


#9 楼

这对我有用:



bg进程

jobs -l查找进程号

tmux启动shell窗口管理器
reptyr -L PROCESSNUMBER


reptyr-L是使它正常工作所必需的:

-L Like '-l', but also redirect the child's stdio to the slave.

由于此错误:

$ reptyr 30622

[-] Unable to open the tty in the child.
Unable to attach to pid 30622: Permission denied


并带有-L

$ reptyr -L 30622
Opened a new pty: /dev/pts/4