How to prevent a background process from being stopped after closing SSH client in Linux
Solution 1
Check out the "nohup" program.
Solution 2
I would recommend using GNU Screen. It allows you to disconnect from the server while all of your processes continue to run. I don't know how I lived without it before I knew it existed.
Solution 3
When the session is closed the process receives the SIGHUP signal which it is apparently not catching. You can use the nohup
command when launching the process or the bash built-in command disown -h
after starting the process to prevent this from happening:
> 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.
Solution 4
daemonize? nohup? SCREEN? (tmux ftw, screen is junk ;-)
Just do what every other app has done since the beginning -- double fork.
# ((exec sleep 30)&)
# grep PPid /proc/`pgrep sleep`/status
PPid: 1
# jobs
# disown
bash: disown: current: no such job
Bang! Done :-) I've used this countless times on all types of apps and many old machines. You can combine with redirects and whatnot to open a private channel between you and the process.
Create as coproc.sh:
#!/bin/bash
IFS=
run_in_coproc () {
echo "coproc[$1] -> main"
read -r; echo $REPLY
}
# dynamic-coprocess-generator. nice.
_coproc () {
local i o e n=${1//[^A-Za-z0-9_]}; shift
exec {i}<> <(:) {o}<> >(:) {e}<> >(:)
. /dev/stdin <<COPROC "${@}"
(("\$@")&) <&$i >&$o 2>&$e
$n=( $o $i $e )
COPROC
}
# pi-rads-of-awesome?
for x in {0..5}; do
_coproc COPROC$x run_in_coproc $x
declare -p COPROC$x
done
for x in COPROC{0..5}; do
. /dev/stdin <<RUN
read -r -u \${$x[0]}; echo \$REPLY
echo "$x <- main" >&\${$x[1]}
read -r -u \${$x[0]}; echo \$REPLY
RUN
done
and then
# ./coproc.sh
declare -a COPROC0='([0]="21" [1]="16" [2]="23")'
declare -a COPROC1='([0]="24" [1]="19" [2]="26")'
declare -a COPROC2='([0]="27" [1]="22" [2]="29")'
declare -a COPROC3='([0]="30" [1]="25" [2]="32")'
declare -a COPROC4='([0]="33" [1]="28" [2]="35")'
declare -a COPROC5='([0]="36" [1]="31" [2]="38")'
coproc[0] -> main
COPROC0 <- main
coproc[1] -> main
COPROC1 <- main
coproc[2] -> main
COPROC2 <- main
coproc[3] -> main
COPROC3 <- main
coproc[4] -> main
COPROC4 <- main
coproc[5] -> main
COPROC5 <- main
And there you go, spawn whatever. the <(:) opens an anonymous pipe via process substitution, which dies, but the pipe sticks around because you have a handle to it. I usually do a sleep 1
instead of :
because its slightly racy, and I'd get a "file busy" error -- never happens if a real command is ran (eg, command true
)
"heredoc sourcing":
. /dev/stdin <<EOF
[...]
EOF
This works on every single shell I've ever tried, including busybox/etc (initramfs). I've never seen it done before, I independently discovered it while prodding, who knew source could accept args? But it often serves as a much more manageable form of eval, if there is such a thing.
Solution 5
nohup blah &
Substitute your process name for blah!
Related videos on Youtube
Berkyjay
Updated on October 18, 2020Comments
-
Berkyjay over 3 years
I'm working on a Linux machine through SSH (Putty). I need to leave a process running during the night, so I thought I could do that by starting the process in background (with an ampersand at the end of the command) and redirecting stdout to a file.
To my surprise, that doesn't work. As soon as I close the Putty window, the process is stopped.
How can I prevent that from happening??
-
tripleee almost 3 yearsIf you want to force the session to remain open, see stackoverflow.com/questions/25084288/keep-ssh-session-alive
-
-
David Nehme over 15 yearsyou might want to add redirect standard out and standard error.
-
user3532201 over 15 yearsThis is one of the greatest pieces of software I've ever used. Seriously. I have it running on a BSD box that I ssh into from EVERYWHERE, and can simply re-attach to my screen and have all of my terminals where I'm doing all sorts of stuff.
-
willasaywhat over 15 yearsI can attest to this one. Screen is a great application. The ability to re-attach is amazing, and saves a lot of potentially lost work.
-
user3532201 over 15 yearsI even use it on local machines, and attach multiple xterms to the same screen session (screen -x). That way I can open up many windows within my screen session, and freely switch my various xterms from window-to-window.
-
Jonas Engström over 15 yearsscreen is definately on my top 3 too, truly awesome software.
-
Lawrence Hutton over 15 yearsDepends on whether you need to reconnect to the backgrounded app or not. If you do, then, yeah, screen is the only way to fly. If it's fire-and-forget, though, then nohup fits the bill just as nicely, if not better.
-
Josh about 15 yearsThere is also 'dtach' which implements only screen's detach mechanism, however it's a bit harder to use but gives control over the socket file that gets created for a detached process. I would recommend using dtach if this were a non-interactive scripted process that needed to remotely launch processes. Otherwise just use screen, it's easier.
-
Chas. Owens about 15 yearsnohup redirects stdout and stderr to nohup.out (or nohup.out and nohup.err depending on the version), so unless you are running multiple commands it is not necessary.
-
Rob over 14 yearsWhy don't you put the source on github or bitbucket?
-
Jonathan Leffler over 14 yearsWhy does the absence of the source from github warrant a downvote?
-
Aman Jain over 14 yearsyeah, screen is awesome, its like a non-gui vnc session :)
-
Derek Dahmer almost 14 yearsHow do you stop it afterwards?
-
JesperE almost 14 yearsLog in and do "kill <pid>". Use "pidof" if you don't know the pid.
-
anthonyrisinger about 12 yearswhy the down vote ... so what if the question is old; it's obviously relevant considering there are 11 other answers that suck. this solutions is, sans systemd, the idiomatic and accepted way to daemonize for the last 30 years, not pointless apps, eg. nohup et al.
-
THESorcerer almost 12 yearsPS anthonyrisinger, you are good, i give you that but ... 30 years ? i bet that is a solution when &, bg, nohup or screen was not there yet, and no offense i appreciate your knowledge but that is far too complicated to use it :)
-
Christian K. almost 12 yearsAdvantage here is that disown works for processes which have already been started.
-
anthonyrisinger over 11 years(aside: see Tmux) although this vastly predates me [1987],
&
(asynchronous execution) was introduced by the Thompson shell in 1971, for the first version of UNIX ... so it literally "has always been" ;-) alas, I was too conservative -- it's actually been 41 years. -
Alex D over 11 yearsno matter how good your answer is, sometimes somebody on SO won't like it and will downvote. It's better not to worry about it too much.
-
KCD about 11 yearsYou can use
nohup command > /dev/null 2>&1 &
to run in the background without creating any stdout or stderr output (nonohup.out
file) -
Stewart almost 11 yearsDoes 'jobspec' mean the pid?
-
Stewart almost 11 yearsNo worries, found this answer here stackoverflow.com/questions/625409/…
-
tbc0 almost 11 yearsThis technique doesn't work when trying to start a job programmatically via ssh, e.g. '$ ssh myhost "((exec sleep 30)&)"'
-
anthonyrisinger over 10 years@tbc0 sure it does; Ctrl^C the ssh client after it hangs then login to the machine... you will find the
sleep 30
command is still running. i'm not sure off-hand why ssh does not release (though i'd guess the sleep process still holds a ref to ssh's pty or similar) but regardless, the sleep command is unaffected by any signals sent (such as the Ctrl^C) and will persist after ssh closes. -
anthonyrisinger over 10 years@tbc0 ...try
ssh myhost "((exec sleep 500)&) >/dev/null"
-
tbc0 over 10 years@anthonyrisinger ok, that works. I think this is cleaner:
ssh myhost 'sleep 500 >&- 2>&- <&- &'
TMTOWTDI ;) -
Sergey over 10 yearsWhat if I need to provide some input? For example, I have a long-running script that I need to run in the background but it first asks for my FTP password.
nohup
doesn't help in this case. Is there a way to fiddle withCtrl+Z
/bg
? -
gerlos about 10 years+1 for screen. Or, as an alternative, tmux (I like this one more than screen) or even byobu, which is a nice frontend for screen or tmux. You can just type screen to get a shell to use and return later at any time, or run your command with screen, like "screen command": the screen session will exist as long as the process "command" exist, and if it's something very long, you can go back and look at its standard output at any time.
-
Anomaly over 8 yearsSince I'm lazy and bad at memorizing cryptic sequences of characters, I wrote this, based on what @KCD said, and have been using it a lot.
-
tymik almost 8 yearsassuming that
yum
is the right tool, when you don't know the distro, is not good. you should make it clear on which distrosscreen
can be installed withyum
. -
Hamy over 7 yearsThis is great. the only solution that actually works in busybox. it deserves more upvotes
-
Berkyjay over 7 yearsCan this be used to run binary executables?
-
haccks over 7 years@GetFree; Yes. You can.
-
Berkyjay over 7 yearsAdd an example please. The answer as it is right now looks like it's good only for script files.
-
haccks over 7 years@GetFree; Added the example. Let me know if you have any problem.
-
DepressedDaniel about 7 years@JonathanLeffler IMHO listing all the cool options of a program that is not publicly available in any form (not even commercially) borders on wasting the reader's time.
-
Tino about 7 yearsThis does not work at my side as this does not shield the program from getting SIGHUP when the ctty is closed. I have a program which must not receive SIGHUP, ever.
nohup
does not work, as it does not prevent SIGHUP, it just defaults to ignore it, which need not prevail. As I do not havescreen
nortmux
norat
nor similar, I need a way on shell level to disassociate a program from the ctty for sure. The only way I found was a hack to start the program withssh -T remote '(program&)&'
which makes it impossible to background the program in an interactivessh
session. -
mabalenk about 7 yearsLinode website offers a good introduction on how to use
screen
. -
kilgoretrout over 5 yearsthis is the way to go