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?)
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?)
Unrfortunately
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'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 ofO_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.
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).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
.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
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.