简体   繁体   English

如何从 Python 脚本运行 nohup 命令?

[英]How to run nohup command from Python script?

I have a simple question.我有一个简单的问题。 I have tried to search for a solution but there are no answers which would explain what I need.我试图寻找解决方案,但没有答案可以解释我需要什么。

The question is: How do I start a nohup command from Python?问题是:如何从 Python 启动nohup命令? Basically the idea is, that I have a Python script which prepares my environment and I need it to launch multiple scripts with nohup commands.基本上这个想法是,我有一个 Python 脚本来准备我的环境,我需要它来使用nohup命令启动多个脚本。 How do I start a nohup command like nohup python3 my_script.py & from within a running Python script to have that nohup command running even after I log out?如何从正在运行的 Python 脚本中启动nohup命令,例如nohup python3 my_script.py &以在我注销后运行该 nohup 命令?

Thank you谢谢

You do not need nohup -- not even in shell, and even less so in Python.你不需要nohup —— 甚至在 shell 中不需要,在 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).将 HUP 信号配置为忽略(很少相关:如果一个进程在 TTY 上没有句柄,则无论如何都不会在该 TTY 退出时收到通知;shell 仅在交互模式下将信号传播给子进程,而不是在运行脚本时) .
  • If stdout is a terminal, redirects it to nohup.out如果 stdout 是终端,则将其重定向到nohup.out
  • If stderr is a terminal, redirects it to wherever stdout was already redirected.如果 stderr 是终端,则将其重定向到 stdout 已重定向的任何位置。
  • Redirects stdin to /dev/null将标准输入重定向到/dev/null

That's it.就是这样。 There's no reason to use nohup to do any of those things;没有理由使用nohup来做任何这些事情; they're all trivial to do without it:没有它,它们都是微不足道的:

  • </dev/null redirects stdin from /dev/null in shell; </dev/null重定向标准输入从/dev/null在壳; stdin=subprocess.DEVNULL does so in Python. stdin=subprocess.DEVNULL在 Python 中这样做。
  • >nohup.out redirects stdout to nohup.out in shell; >nohup.out将标准输出重定向到 shell 中的nohup.out stdout=open('nohup.out', 'w') does so in Python. stdout=open('nohup.out', 'w')在 Python 中这样做。
  • 2>&1 makes stderr go to the same place as stdout in shell; 2>&1使 stderr 和 shell 中的 stdout 到同一个地方; stderr=subprocess.STDOUT does so in Python. stderr=subprocess.STDOUT在 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.由于您的进程没有通过上述重定向连接到终端,因此当该终端关闭时,它不会隐式地获得 HUP。 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.所述subprocess.Popen参数start_new_session=True分裂子进程成从在Python父一个单独的组,所以发送到父的进程组作为一个整体母体不会被儿童接收。
  • 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.使用signal.signal(signal.SIGHUP, signal.SIG_IGN) preexec_fn , signal.signal(signal.SIGHUP, signal.SIG_IGN)添加preexec_fn更加明确,即使收到一个 SIGHUP,孩子也应该默认忽略 SIGHUP。

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):把这一切放在一起可能看起来像(如果你真的想让日志转到一个名为nohup.out的文件——我建议选择一个更好的名字):

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.NOHUP, signal.SIG_IGN)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM