How do I put an already-running process under nohup?
我有一个进程已经运行了很长时间,不想结束它。
如何将其置于nohup下(即,即使关闭终端,如何使其继续运行?)
使用bash的作业控制将进程发送到后台:
假设由于某种原因CtrL+Z也不工作,转到另一个终端,找到进程ID(使用
1 2 | kill -SIGSTOP PID kill -SIGCONT PID |
将正在运行的作业与shell(=makeit nohup)分开的命令是
从bash手册页(man bash):
disown [-ar] [-h] [jobspec ...]
Without options, each jobspec is removed from the table of active jobs. If the -h option is given, each jobspec is not
removed from the table, but is marked so that SIGHUP is not sent to the job if the shell receives a SIGHUP. If no jobspec is
present, and neither the -a nor the -r option is supplied, the current job is used. If no jobspec is supplied, the -a option
means to remove or mark all jobs; the -r option without a jobspec argument restricts operation to running jobs. The return
value is 0 unless a jobspec does not specify a valid job.
这意味着,
1 | disown -a |
将从作业表中删除所有作业并使其不显示
以上是很好的答案,我只是想补充一点:
你不能用一个pid或进程来处理
作业是一个附加到shell的流程概念,因此您必须将作业抛到后台(而不是挂起它),然后再拒绝它。
问题:
1 2 3 4 | % jobs [1] running java [2] suspended vi % disown %1 |
请参阅http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/有关Unix作业控制的更详细的讨论。
不幸的是,
某些风格的Unix(例如,AIX和Solaris)在
1 | nohup -p pid |
参见http://en.wikipedia.org/wiki/nohup
节点的答案确实很好,但它留下了一个问题:如何才能得到stdout和stderr重定向。我在Unix&Linux上找到了一个解决方案,但它也不完整。我想合并这两个解决方案。这里是:
为了进行测试,我编写了一个名为loop.sh的小型bash脚本,它以无限循环的形式打印了一分钟睡眠的PID。
1 | $./loop.sh |
现在以某种方式获取这个过程的PID。通常情况下,
现在我们可以切换到另一个终端(或按^Z键在同一个终端)。现在,
1 | $ gdb -p <PID> |
这将停止脚本(如果正在运行)。它的状态可以通过
1 2 3 4 5 | T Stopped, either by a job control signal or because it is being traced + is in the foreground process group (gdb) call close(1) $1 = 0 |
CLOSE(1)成功时返回零。
1 2 | (gdb) call open("loop.out", 01102, 0600) $6 = 1 |
如果成功,open(1)返回新的文件描述符。
此开度与
我检查了/usr/include/bits/fcntl.h头文件中的值。
输出文件可以用
如果我们得到-1作为返回值,那么
现在我们可以检查新重定向的文件。
1 | loop.sh <PID> truey 1u REG 0,26 0 15008411 /home/truey/loop.out |
如果需要,我们可以将stderr重定向到另一个文件,如果我们想再次使用
现在附件
1 2 3 | (gdb) detach Detaching from program: /bin/bash, process <PID> (gdb) q |
如果脚本被其他终端的
1 2 | ^Z [1]+ Stopped ./loop.sh |
(现在我们的状态和一开始按
现在我们可以检查作业的状态:
1 2 3 4 5 | $ ps -f 24522 UID PID PPID C STIME TTY STAT TIME CMD <UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh $ jobs [1]+ Stopped ./loop.sh |
所以进程应该在后台运行,并与终端分离。
1 2 3 4 5 6 | $ bg %1 [1]+ ./loop.sh & $ disown -h %1 $ ps -f <PID> UID PID PPID C STIME TTY STAT TIME CMD <UID> <PID><PPID> 0 11:16 pts/36 S 0:00 /bin/bash ./loop.sh |
现在我们可以不再打电话了。进程继续在后台运行。如果我们退出它的ppid变为1(init(1)进程),控制终端将变为未知。
1 2 3 4 5 6 7 8 | $ ps -f <PID> UID PID PPID C STIME TTY STAT TIME CMD <UID> <PID> 1 0 11:16 ? S 0:00 /bin/bash ./loop.sh $ /usr/bin/lsof -p <PID> ... loop.sh <PID> truey 0u CHR 136,36 38 /dev/pts/36 (deleted) loop.sh <PID> truey 1u REG 0,26 1127 15008411 /home/truey/loop.out loop.sh <PID> truey 2u CHR 136,36 38 /dev/pts/36 (deleted) |
评论
gdb工具可以自动创建包含命令的文件(例如loop.gdb)并运行
1 2 3 4 5 6 | call close(1) call open("loop.out", 01102, 0600) # call close(2) # call open("loop.err", 01102, 0600) detach quit |
或者可以使用以下一个内衬:
1 | gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID> |
我希望这是对解决方案的一个相当完整的描述。
将运行进程发送到nohup(http://en.wikipedia.org/wiki/nohup)
以东十一〔十二〕号,对我不起作用。
然后我试了下面的命令,效果很好
运行一些命令,比如说
ctrl+zabbd停止(暂停)程序并返回shell。
键入
这个过程相当于运行
这些简单的步骤将允许您在保持进程运行的同时关闭终端。
这不会影响到
在我的AIX系统上,我尝试了
1 | nohup -p processid> |
这很管用。它继续运行我的进程,即使在关闭终端窗口之后。我们使用ksh作为默认shell,因此
在tcshell中,这在UbuntuLinux上对我很有用。
ctrlzakbd暂停