0

When running a long-running command in the background over SSH from a non-interactive shell script, I noticed the process continues running on the remote machine without using nohup, disown, or similar tools.

Remote Environment (SSH target):

  • Linux 6.12.9
  • OpenSSH 9.9p1, OpenSSL 3.3.2
  • Login Shell: bash 5.2.37
    • Also for non-interactive sessions (verified by ssh -T $HOST "echo \$SHELL")
  • Distribution: NixOS 24.11

On the client side, I can execute:

# Closing outgoing FDs (stdout and stderr) important to end # SSH session immediately (EOF). We also need a non-interactive # session (-T). ssh -T $HOST "long_running_command >/dev/null 2>/dev/null &" 

to start a long running command on the remote without having to keep the SSH session alive.

I expected that background jobs would terminate or receive SIGHUP when the SSH session ends. However, the process is automatically reparented to PID 1 (init) and keeps running. I can verify this using htop, ps, et. al.

Why does this work without nohup or disown?

  • Why does it just work like that? Why are no SIGHUP or similar events being send to long_running_command?
  • Why does job control (&) work in bash in non-interactive mode?
  • Who decides that the running background job will switch ownership to the init process? Bash? Is this documented?
2
  • About the reparenting a process to PID 1, that is the result of a process fork(2)-ing and the parent terminating without wait(2)-ing for children - forked child clone gets "reparented" to PID 1. This is documented, for example in OpenBSD's wait(2) manpage. Commented Jan 17 at 8:58
  • Forking twice and the first forked process exiting is an old technique. Then the (2nd) child can perform library calls to ignore signals the same as nohup does (it's not magic). Commented Jan 17 at 9:38

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.