如何将已经运行的进程置于 nohup 下?
我有一个进程已经运行了很长时间并且不想结束它。
如何将其放在nohup下(即如何使其即使关闭终端也继续运行?)
I have a process that is already running for a long time and don't want to end it.
How do I put it under nohup (that is, how do I cause it to continue running even if I close the terminal?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
使用 bash 的作业控制将进程发送到后台:
bg
在后台运行它。disown -h [job-spec]
其中 [job-spec] 是作业编号(例如第一个运行的作业的%1
;使用查找您的编号>jobs
命令),以便在终端关闭时作业不会被终止。Using the Job Control of bash to send the process into the background:
bg
to run it in the background.disown -h [job-spec]
where [job-spec] is the job number (like%1
for the first running job; find about your number with thejobs
command) so that the job isn't killed when the terminal closes.假设由于某种原因 Ctrl+Z 也不起作用,请转到另一个终端,找到进程 ID(使用
ps
)并运行:< code>SIGSTOP 将暂停进程,
SIGCONT
将在后台恢复进程。 所以现在,关闭两个终端不会停止您的进程。Suppose for some reason Ctrl+Z is also not working, go to another terminal, find the process id (using
ps
) and run:SIGSTOP
will suspend the process andSIGCONT
will resume the process, in background. So now, closing both your terminals won't stop your process.将正在运行的作业与 shell 分离的命令(= 使其为 nohup)是
disown
,它是一个基本的 shell 命令。来自 bash 手册页 (man bash):
这意味着,一个简单的操作
将从作业表中删除所有作业并使它们成为 nohup
The command to separate a running job from the shell ( = makes it nohup) is
disown
and a basic shell-command.From bash-manpage (man bash):
That means, that a simple
will remove all jobs from the job-table and makes them nohup
上面这些都是很好的答案,我只是想添加一个说明:
你不能
否认
一个pid或进程,你否认
一个工作,这是一个重要的区别。作业是附加到 shell 的进程的概念,因此您必须将作业放入后台(而不是挂起它),然后放弃它。
问题:
请参阅 http://www.quantprinciple.com/invest /index.php/docs/tipsandtricks/unix/jobcontrol/
有关 Unix 作业控制的更详细讨论。
These are good answers above, I just wanted to add a clarification:
You can't
disown
a pid or process, youdisown
a job, and that is an important distinction.A job is something that is a notion of a process that is attached to a shell, therefore you have to throw the job into the background (not suspend it) and then disown it.
Issue:
See http://www.quantprinciple.com/invest/index.php/docs/tipsandtricks/unix/jobcontrol/
for a more detailed discussion of Unix Job Control.
不幸的是
disown
是 bash 特有的,并非在所有 shell 中都可用。某些 Unix 版本(例如 AIX 和 Solaris)在
nohup
命令本身上有一个选项,可以应用于正在运行的进程:请参阅 http://en.wikipedia.org/wiki/Nohup
Unfortunately
disown
is specific to bash and not available in all shells.Certain flavours of Unix (e.g. AIX and Solaris) have an option on the
nohup
command itself which can be applied to a running process:See http://en.wikipedia.org/wiki/Nohup
Node 的答案确实很棒,但它留下了一个悬而未决的问题:如何重定向 stdout 和 stderr。 我在 Unix & 上找到了解决方案 Linux,但它还不完整。 我想合并这两个解决方案。 它是这样的:
为了我的测试,我制作了一个名为loop.sh的小bash脚本,它在无限循环中打印它自己的pid并进行一分钟的睡眠。
现在以某种方式获取该进程的 PID。 通常
ps -C Loop.sh
就足够了,但在我的情况下它被打印了。现在我们可以切换到另一个终端(或在同一终端中按 ^Z )。 现在 gdb 应该附加到这个进程。
这将停止脚本(如果正在运行)。 可以通过
ps -f
检查其状态,其中STAT
字段为“T+”(或者在 ^Z 'T' 的情况下),这意味着(man ps(1))Close(1) 成功时返回零。
如果成功,Open(1) 返回新的文件描述符。
此 open 等同于
open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
。可以应用
O_RDWR
O_WRONLY
,但/usr/sbin/lsof
表示所有 std* 文件处理程序为“u”(FD
列),即O_RDWR
。我检查了 /usr/include/bits/fcntl.h 头文件中的值。
输出文件可以使用
O_APPEND
打开,就像nohup
那样,但man open(2)
不建议这样做,因为可能NFS 问题。如果我们得到 -1 作为返回值,则
call perror("")
会打印错误消息。 如果我们需要 errno,请使用p errno
gdb 命令。现在我们可以检查新重定向的文件。
/usr/sbin/lsof -p
打印:如果我们愿意,我们可以将 stderr 重定向到另一个文件,如果我们想使用
call close(2)
并使用不同的文件名再次调用 open(...)
。现在附加的
bash
必须被释放,我们可以退出gdb
:如果脚本被
gdb
从另一个终端停止,它会继续运行。 我们可以切换回loop.sh的终端。 现在它不会向屏幕写入任何内容,而是运行并写入文件。 我们必须把它放到后台。 所以按^Z
。(现在我们处于与开始时按下
^Z
相同的状态。)现在我们可以检查作业的状态:
因此进程应该在后台运行并与终端分离。
jobs
命令输出中方括号中的数字标识bash
内的作业。 我们可以在以下内置bash
命令中使用,在作业编号前应用“%”符号:现在我们可以退出调用 bash。 该进程继续在后台运行。 如果我们退出它的 PPID 就会变成 1(init(1) 进程)并且控制终端变得未知。
注释
gdb 的东西可以自动创建一个包含命令的文件(例如loop.gdb)并运行
gdb -q -x Loop.gdb -p
。 我的loop.gdb 看起来像这样:或者可以使用以下一个衬垫:
我希望这是对解决方案的相当完整的描述。
Node's answer is really great, but it left open the question how can get stdout and stderr redirected. I found a solution on Unix & Linux, but it is also not complete. I would like to merge these two solutions. Here it is:
For my test I made a small bash script called loop.sh, which prints the pid of itself with a minute sleep in an infinite loop.
Now get the PID of this process somehow. Usually
ps -C loop.sh
is good enough, but it is printed in my case.Now we can switch to another terminal (or press ^Z and in the same terminal). Now
gdb
should be attached to this process.This stops the script (if running). Its state can be checked by
ps -f <PID>
, where theSTAT
field is 'T+' (or in case of ^Z 'T'), which means (man ps(1))Close(1) returns zero on success.
Open(1) returns the new file descriptor if successful.
This open is equal with
open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)
.Instead of
O_RDWR
O_WRONLY
could be applied, but/usr/sbin/lsof
says 'u' for all std* file handlers (FD
column), which isO_RDWR
.I checked the values in /usr/include/bits/fcntl.h header file.
The output file could be opened with
O_APPEND
, asnohup
would do, but this is not suggested byman open(2)
, because of possible NFS problems.If we get -1 as a return value, then
call perror("")
prints the error message. If we need the errno, usep errno
gdb comand.Now we can check the newly redirected file.
/usr/sbin/lsof -p <PID>
prints:If we want, we can redirect stderr to another file, if we want to using
call close(2)
andcall open(...)
again using a different file name.Now the attached
bash
has to be released and we can quitgdb
:If the script was stopped by
gdb
from an other terminal it continues to run. We can switch back to loop.sh's terminal. Now it does not write anything to the screen, but running and writing into the file. We have to put it into the background. So press^Z
.(Now we are in the same state as if
^Z
was pressed at the beginning.)Now we can check the state of the job:
So process should be running in the background and detached from the terminal. The number in the
jobs
command's output in square brackets identifies the job insidebash
. We can use in the following built inbash
commands applying a '%' sign before the job number :And now we can quit from the calling bash. The process continues running in the background. If we quit its PPID become 1 (init(1) process) and the control terminal become unknown.
COMMENT
The gdb stuff can be automatized creating a file (e.g. loop.gdb) containing the commands and run
gdb -q -x loop.gdb -p <PID>
. My loop.gdb looks like this:Or one can use the following one liner instead:
I hope this is a fairly complete description of the solution.
简单且最简单的步骤
Ctrl + Z
----------> 暂停进程bg
--------------> 恢复并运行后台disown %1
-------------> 仅当您需要与终端分离时才需要Simple and easiest steps
Ctrl + Z
----------> Suspends the processbg
--------------> Resumes and runs backgrounddisown %1
-------------> required only if you need to detach from the terminal将正在运行的进程发送到 nohup (http://en.wikipedia.org/wiki/Nohup)
nohup -p pid
,它对我不起作用然后我尝试了以下命令,它工作得很好
运行一些命令,
说
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
。Ctrl+Z 停止(暂停)程序并返回 shell。
bg
在后台运行它。disown -h
以便在终端关闭时进程不会被终止。输入
exit
退出 shell,因为现在您可以开始了,因为该操作将在其自己的进程中在后台运行,因此它不依赖于 shell。此过程相当于运行
nohup SOMECOMMAND
。To send running process to nohup (http://en.wikipedia.org/wiki/Nohup)
nohup -p pid
, it did not worked for meThen I tried the following commands and it worked very fine
Run some SOMECOMMAND,
say
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.Ctrl+Z to stop (pause) the program and get back to the shell.
bg
to run it in the background.disown -h
so that the process isn't killed when the terminal closes.Type
exit
to get out of the shell because now you're good to go as the operation will run in the background in its own process, so it's not tied to a shell.This process is the equivalent of running
nohup SOMECOMMAND
.bg
- 这将使作业进入后台并返回运行状态processdisown -a
- 这将剪切作业的所有附件(因此您可以关闭终端,它仍然会运行)这些简单的步骤将允许您在保持进程运行的同时关闭终端。
它不会加上
nohup
(根据我对你的问题的理解,你在这里不需要它)。bg
- this will put the job in background and return in running processdisown -a
- this will cut all the attachment with job (so you can close the terminal and it will still run)These simple steps will allow you to close the terminal while keeping process running.
It wont put on
nohup
(based on my understanding of your question, you don't need it here).在我的 AIX 系统上,我尝试过,
效果很好。 即使关闭终端窗口后它仍然继续运行我的进程。 我们将 ksh 作为默认 shell,因此
bg
和disown
命令不起作用。On my AIX system, I tried
This worked well. It continued to run my process even after closing terminal windows. We have ksh as default shell so the
bg
anddisown
commands didn't work.