事后远程 nohup 与 tcsh

wfa*_*ulk 11 kill nohup tcsh

我在运行长期(数周?)进程的 xterm 中有一个 tcsh 实例。它运行的 Xvnc 服务器在杂草中消失了;它消耗 100% 的 CPU 并且没有响应。(这是一个已知的错误,我知道它是不可恢复的。)

长期进程目前在标准输出上阻塞。

有什么办法可以杀死一个底层进程——tcsh、xterm 等等——并保持这个长期进程运行?

(拜托,没有关于 的答案screen。我知道。这不是我的过程;这是用户的。他们不会学习。)

qua*_*ote 17

这篇文章可能会有所帮助。建议是:

  1. 后台进程(使用 Ctrl-Z,然后是bg
  2. 运行disown -h %[jobid](可能是 bash-ism,所以你必须为 tcsh 翻译)

坏消息,当然是,BG将需要在这个过程中运行相同的外壳做......但它可能正在后台运行。

真正的坏消息是,不认通话可能需要在同一个壳来完成。在这种情况下,是的,你完蛋了。但我不确定,也许 root 可以强制断开它。

唔。可能的好消息——tcsh 会自动拒绝

如果tcsh异常退出,退出时会自动拒绝后台运行的作业。

所以,如果你的长期进程已经在后台运行,杀死它的 tcsh 父进程应该允许它继续。该过程现在与起始终端断开连接。(如果不是,请参阅上面的“坏消息”。)

不幸的是,它不是屏幕,所以没有真正的重新连接。你可以用 gdb 伪造它(同样,从第一个链接):

[...] 通过一些肮脏的黑客攻击,重新打开进程的 stdout/stderr/stdin 并非不可能。

所以你仍然可以创建一个空白屏幕窗口(例如运行睡眠)。

然后使用 gdb 例如附加到进程,做一些 call close(0)
call close(1)
call close(2)
call open("/dev/pts/xx", ...)
call dup(0)
调用 dup(0)
分离

该过程的输出将进入屏幕。它不会附加到那个屏幕终端,因此例如[原文如此] 会终止“睡眠”命令,而不是进程,但这对 OP 来说已经足够了。

我想知道在这个过程中是否不应该有“call dup(1)”和“call dup(2)”......

  • 这完全救了我的屁股。我遇到了我最初发布的相同问题,即当 X 服务器(以及我猜是中间的 xterm)发生冲突时,进程在 STDOUT 上阻塞。事实证明,除了关闭 STDOUT 之外,我真的不需要做任何事情。该输出无关紧要;真实数据在某个地方的日志文件中。所以我能够连接到 gdb,运行“call close(1)”然后“cont”,它又继续前进了。非常感谢! (2认同)
  • 可能值得指出的是,将“Ctrl-Z”发送到前台进程和将 SIGSTOP 发送到其 pid 是一回事。(SIGCONT 再次启动该过程。)我不知道这对处于相同情况的其他人是否有帮助,但是,在我的快速测试中,发送 SIGSTOP 后跟 SIGCONT 重复“Ctrl-Z”后跟 `bg `. (2认同)