nohup vs &
A guide to running long-running processes in SSH sessions using &, nohup, and disown to prevent hangup signals from terminating your commands.
I've gotten a lot of questions in my time about firing off a long running process in an ssh session and having them stop after logging out. This is because every command you run in a bash sessions (via your local terminal or ssh) has an associated hangup signal. When you log out of the sessions (i.e. close your terminal or kill an ssh session), the shell will terminate all of the sub-commands associated. This can be problematic for people who want to log in, run a script to start a server, and log out.
For those who need a more robust way of doing this, I'd strongly suggest creating a systemd service unit. With this, you'll be able to start, stop, restart, and monitor the process via systemctl rather than parsing through ps output. However, if you're looking for a quick and dirty way to just run something, we have & and nohup.
&
The ampersand, &, is used to run a command in the background of a shell. It's useful in situations where you're starting a long running process in a shell and don't need to follow any output. The problem most people run into with this is that they run a command using &, log out of the shell, and then their process is all of a sudden gone. This is because running a command with the & doesn't prevent hangup, it just hides the process in the background. When you do something like ./start_server.sh & and then log out of the shell, that command is killed as a sub-command of the current shell session.
nohup
nohup is used to run a command that ignores hangup signals (SIGHUP), making it immune to terminal disconnection. By default, nohup redirects stdout and stderr to a file called nohup.out in the current directory. You can combine nohup with & for the best of both worlds:
nohup ./start_server.sh &This runs the command in the background AND makes it immune to hangup signals. However, the process still remains in the shell's job list until you exit the session.
disown
To be really sure that your process wont be interrupted, you'll have to disown the process.
./run_the_thing &
disown %1Or simply:
./run_the_thing &
disownThis removes the process from the shell's job list, completely detaching it from the current session.
Other Alternatives
For more robust session management, consider:
Screen/Tmux: Terminal multiplexers that allow you to detach and reattach sessions:
screen -S myserver
./start_server.sh
# Press Ctrl+A, then D to detachSystemd: For production systems, create a proper service unit:
sudo systemctl start myservice
sudo systemctl enable myserviceThese provide better process management, logging, and monitoring capabilities than the quick-and-dirty methods above.
← all writing