You do not need nohup -- not even in shell, and even less so in Python. It does the following things:
- Configures the HUP signal to be ignored (rarely relevant: if a process has no handles on a TTY it isn't going to be notified when that TTY exits regardless; the shell only propagates signals to children in interactive mode, not when running scripts).
- If stdout is a terminal, redirects it to
nohup.out
- If stderr is a terminal, redirects it to wherever stdout was already redirected.
- Redirects stdin to
/dev/null
That's it. There's no reason to use nohup to do any of those things; they're all trivial to do without it:
</dev/null redirects stdin from /dev/null in shell; stdin=subprocess.DEVNULL does so in Python.
>nohup.out redirects stdout to nohup.out in shell; stdout=open('nohup.out', 'w') does so in Python.
2>&1 makes stderr go to the same place as stdout in shell; stderr=subprocess.STDOUT does so in Python.
Because your process isn't attached to the terminal by virtue of the above redirections, it won't implicitly get a HUP when that terminal closes. If you're worried about a signal being sent to the parent's entire process group, however, you can avoid that by splitting off the child into a separate one:
- The
subprocess.Popen argument start_new_session=True splits the child process into a separate group from the parent in Python, so a parent sent to the process group of the parent as a whole will not be received by the child.
- Adding a
preexec_fn with signal.signal(signal.SIGHUP, signal.SIG_IGN) is even more explicit that the child should by default ignore a SIGHUP even if one is received.
Putting this all together might look like (if you really do want logs to go to a file named nohup.out -- I would suggest picking a better name):
import subprocess, signal
subprocess.Popen(['python3', 'my_script.py'],
stdin=subprocess.DEVNULL,
stdout=open('nohup.out', 'w'),
stderr=subprocess.STDOUT,
start_new_session=True,
preexec_fn=(lambda: signal.signal(signal.SIGHUP, signal.SIG_IGN)))
nohupis useless even in bash -- it does nothing you can't do just with some redirections and potentially the shelldisownbuiltin (which has, and needs, no Python equivalent). There's no reason to use it in Python; none whatsoever.subprocess.Popen(['python3', 'my_script.py'], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True)-- replace thesubprocess.DEVNULLs for stdout and stderr with pointers to a file if you want (nohup's own default isnohup.out, but you can call it anything you want).