Use case: Let’s say you logged into a remote machine, you executed a command, it is taking time, and you want to logout but you want the process to keep running in the background, you can follow the below steps to accomplish that.
- Suspend process (
Ctrl-z
) - Resume process (
fg
orbg
) - Disown process (
disown
) - Sending process to the background using
&
- Ignore SIGHUP on exit using
nohup
- Capture process errors
2>&1
Suspend process (Ctrl-z
)
For example, you have a long running process like below.
# for demo, creating a long process
for i in $(seq 1 10);do;echo $i;sleep 3;done
Ctrl-z
suspends the process and gives back the focus to the command prompt; it does not kill the process. (I have seen few
developers using Ctrl-z
hoping that it would kill the process.).
$ for i in $(seq 1 10);do;echo $i;sleep 3;done
1
^Z[1] + 72403 suspended sleep 3
In the above example, the running process is suspended using Ctrl-z,
and the focus on the command prompt is given back to us.
The process id is 72403
, and the job id is 1
.
You can view the suspended process using the jobs
command.
$ jobs
[1] + suspended sleep 3
# process still exists
$ ps -ef | grep 72403
501 72403 2015 0 5:35PM ttys016 0:00.00 sleep 3
At this point, if you try to exit
the shell, it will complain.
[1] + 72403 suspended sleep 3
zsh: you have suspended jobs.
Note: jobs
will show all suspended and running jobs in current shell.
If you want to kill the jobs, use kill %n
where n is the job number.
For example kill %2
to kill job 2.
Resume process (fg
or bg
)
Now you have 2 options,
fg
to resume and bring the process running to the foreground (process won’t give prompt to you)bg
to resume and keep the process running in the background
The fg
option will not help in this use case because it will bring back the process and not focus on the command prompt.
Use bg
to resume the process and keep it running in the background.
Note: You can use jobid with fg %n
or bg %n
to resume that specific job.
At this point, we have the process running in the background; now we have the prompt.
If you try to exit
, you will error like below.
exit
[1] + 81703 running for i in $(seq 1 10); do; echo $i; sleep 3; done
zsh: you have running jobs.
Disown process (disown
)
disown
will disown all processes running in the current shell.
Now execute disown -a
or disown %1
(to target a specific job).
To summarize, below are the steps that are done to keep the process running background.
# execute long running process
# Ctrl-z to suspend the process
➜ ~ for i in $(seq 1 10);do;echo $i;sleep 3;done > /tmp/tout
^Z[1] + 83100 suspended sleep 3
# verify jobs
➜ ~ jobs
[1] + suspended sleep 3
# resume the process in background
➜ ~ bg %1
[1] + 83100 continued sleep 3
# disown the process
➜ ~ disown %1
# safe to exit
➜ ~ exit
Sending process to the background using &
By having the &
at the end of the command, the process is sent to the background; this is the same as running a command, suspending the process using Ctrl-z
, and resuming the process using bg
.
You still need to use disown
to run in the background even after exiting the current shell.
For example, below is the script we want to run in the background.
$ more /tmp/test.sh
for i in $(seq 1 10)
do
echo $i
sleep 3
done
Another file which runs above with &
.
$ more /tmp/run_test_bg.sh
/tmp/test.sh > /tmp/tout &
Now if you run /tmp/run_test_bg.sh
& exit the shell, the process will be still running in background.
Ignore SIGHUP on exit using nohup
Usually, the kernel will send a SIGHUP
signal to all the processes that are started if the shell is exited.
In this case, you can use nohup
. If you do nohup /tmp/test.sh &
, you will get appending output to nohup.out
.
nohup
expects the output of the process to be redirected using >
; if not given, it will create nohup.out
in the folder
where nohup
is executed, this file will have the output of the process.
We can use nohup /tmp/test.sh > /tmp/tout &
, this will redirect the output to a file (and it won’t create nohup.out).
If you do not want to capture the output of the process, use /dev/null
to redirect process output (nohup command >
/dev/null
)
Capture process errors 2>&1
If you want to capture process errors that are sent to STDERR, you can redirect errors to STDOUT. The file descriptor
for STDERR is 2 and STDOUT is 1, so 2>&1
, will redirect all the errors to STDOUT.
With that final command would be like below
nohup /tmp/test.sh 2>&1 > /tmp/tout &
I hope the above helped you understand how to send a process background.
– RC
Comments