我可以 nohup/screen 一个已经启动的进程吗?

ojr*_*rac 272 linux unix ssh nohup gnu-screen

我正在通过 SSH 对长时间运行的数据迁移脚本进行一些测试。假设我在下午 4 点左右开始运行脚本;现在,下午 6 点左右,我诅咒自己没有全力以赴screen

有什么办法可以“追溯”nohup一个进程,还是我需要整晚让我的电脑在线?如果无法附加screen到/nohup我已经开始的进程,那为什么?与父/子进程的交互方式有关吗?(我不会接受至少没有解决“为什么”问题的“否”答案——抱歉;))

gha*_*per 215

如果您使用的是 Bash,则可以运行 disown -h job

否认

disown [-ar] [-h] [jobspec ...]
Run Code Online (Sandbox Code Playgroud)

如果没有选项,每个作业规范都会从活动作业表中删除。如果-h给出该选项,则作业不会从表中删除,但会被标记,以便在 shell 收到 SIGHUP 时不会将 SIGHUP 发送到作业。如果 jobspec 不存在,并且没有提供-anor-r选项,则使用当前作业。如果没有提供jobspec,则该-a 选项表示删除或标记所有作业;-r没有 jobspec 参数的选项将操作限制为正在运行的作业。

  • disown 并非特定于 bash。它也在 zsh、ksh93、... (9认同)
  • 生活可能是不公平的。gharper 和我大约在同一时间发布了这个:) (8认同)
  • 你是我的英雄 (4认同)
  • 我发现你实际上必须使用 `disown %1` 如果 1 是 jobspec,不像 fg 或 bg 你只使用 `bg 1` http://www.serverwatch.com/tutorials/article.php/3935306/Detach -Processes-With-Disown-and-Nohup.htm (3认同)

小智 85

使用爬虫

从自述文件:

reptyr - A tool for "re-ptying" programs.
-----------------------------------------

reptyr is a utility for taking an existing running program and
attaching it to a new terminal. Started a long-running process over
ssh, but have to leave and don't want to interrupt it? Just start a
screen, use reptyr to grab it, and then kill the ssh session and head
on home.

USAGE
-----

  reptyr PID

"reptyr PID" will grab the process with id PID and attach it to your
current terminal.

After attaching, the process will take input from and write output to
the new terminal, including ^C and ^Z. (Unfortunately, if you
background it, you will still have to run "bg" or "fg" in the old
terminal. This is likely impossible to fix in a reasonable way without
patching your shell.)
Run Code Online (Sandbox Code Playgroud)

其作者的一些博客文章:


Jul*_*ano 22

要将进程从一个 tty 窃取到您当前的 tty,您可能想尝试以下 hack:

http://www.ucc.asn.au/~dagobah/things/grab.c

它需要一些重新格式化才能编译到当前的 Linux/glibc 版本,但仍然有效。


fre*_*eit 18

当一个进程启动时,STDIN、STDOUT 和 STDERR 连接到某些东西。通常,一旦命令启动,您就无法更改它。在您描述的情况下,这可能是与 ssh 会话相关的 tty。nohup 几乎只是...

command < /dev/null > nohup.out 2>&1
Run Code Online (Sandbox Code Playgroud)

也就是说,将 STDIN 设置为 /dev/null,将 STDOUT 设置为文件,将 STDERR 设置为 STDOUT。Screen 做更复杂的事情,包括设置指向自身的 tty。

我不知道有什么方法可以追溯 nohup 或筛选正在运行的进程。如果您 cd 到 /proc/$pid/fd 并查看 0、1 和 2 指向什么。

您可能对 disown 有一些运气,但如果进程尝试使用 STDIN、STDOUT 或 STDERR 执行任何操作,则不会。

  • 您实际上可以在大多数 Unix 上更改它。这是一个令人作呕的黑客。我喜欢它。:) 您要做的是,使用诸如 ptrace 之类的调试支持连接到进程,然后强制该进程调用 dup2() 以将 0,1,2 重新连接到另一个文件句柄。 (7认同)
  • 是的,你可以改变它。涉及暂停进程 (SIGSTOP),并修改 fd 0、1、2 的文件描述符。然后重新启动 (SIGCONT)。 (3认同)
  • +1 的好评。st(din|out|err) 是问题的另一半,我很欣赏关于从哪里开始寻找的建议,下次我遇到这种情况时。 (2认同)

Mar*_* M. 13

我只能给你一个简单的“不”,没有屏幕部分的原因,我会对你自己的原因感兴趣。

但是你有没有试过disown(内置的bash)

~ $ echo $SHELL
/bin/bash
~ $ type disown
disown is a shell builtin
~ $ help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.
Run Code Online (Sandbox Code Playgroud)


TRS*_*-80 13

Cryopidgrab.c的作者的进一步发展,它将进程冻结到一个文件,然后您运行(在屏幕内)以恢复该进程。


ala*_*anc 9

Solaris/OpenSolaris 上的 nohup 有一个 -p 标志来 nohup 正在运行的进程 - 例如,请参见Solaris 10 nohup 手册页


Dan*_*son 5

我最近看到了一个指向neercs的链接,它是一个使用 libcaca(一个彩色 ascii 艺术库)构建的类似屏幕的实用程序。在其他功能中,它拥有获取现有进程并在您的 neercs(屏幕)会话中重新设置父进程的能力。

但是我没有使用它,所以我无法评论它是否有效。