Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 启动一个完全独立的流程_Python_Python 2.7_Subprocess_Fork_Child Process - Fatal编程技术网

Python 启动一个完全独立的流程

Python 启动一个完全独立的流程,python,python-2.7,subprocess,fork,child-process,Python,Python 2.7,Subprocess,Fork,Child Process,我想从python脚本main.py启动一个进程。具体来说,我想运行以下命令: `nohup python ./myfile.py &` 并且文件myfile.py应该继续运行,即使在main.py脚本退出之后也是如此 我还希望获得新流程的pid 我试过: os.spawnl* os.exec* subprocess.Popen 当main.py脚本退出时,所有这些都将终止myfile.py 更新:我可以在xdg打开时使用os.startfile吗?这是正确的方法吗 示例 a

我想从python脚本
main.py
启动一个进程。具体来说,我想运行以下命令:

`nohup python ./myfile.py &`
并且文件
myfile.py
应该继续运行,即使在
main.py
脚本退出之后也是如此

我还希望获得新流程的
pid

我试过:

  • os.spawnl*
  • os.exec*
  • subprocess.Popen
main.py
脚本退出时,所有这些都将终止
myfile.py


更新:我可以在
xdg打开时使用
os.startfile
吗?这是正确的方法吗


示例

a = subprocess.Popen([sys.executable, "nohup /usr/bin/python25 /long_process.py &"],\
     stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
print a.pid
如果我选中ps aux | grep long_进程
,则没有进程正在运行

long_process.py持续打印某些文本:不退出


我在这里做错了什么吗?

您打开了长期运行的流程,并保留了一条通向它的管道。所以你希望和它谈谈。当你的启动程序脚本退出时,你就不能再和它说话了。长时间运行的进程收到一个
SIGPIPE
并退出

以下内容对我来说很有用(Linux、Python2.7)

创建长时间运行的可执行文件:

$ echo "sleep 100" > ~/tmp/sleeper.sh
运行Python REPL:

$ python
>>>

import subprocess
import os
p = subprocess.Popen(['/bin/sh', os.path.expanduser('~/tmp/sleeper.sh')])
# look ma, no pipes!
print p.pid
# prints 29893
退出REPL并查看进程仍在运行:

>>> ^D
$ ps ax | grep sleeper
29893 pts/0    S      0:00 /bin/sh .../tmp/sleeper.sh
29917 pts/0    S+     0:00 grep --color=auto sleeper
如果要先与已启动的进程通信,然后让它继续运行,则有几个选项:

  • 在长时间运行的进程中处理
    SIGPIPE
    ,不要死在它上面。在启动程序进程退出后,不使用标准输入
  • 使用参数、环境或临时文件传递您想要的任何内容
  • 如果要双向通信,请考虑使用命名管道()或套接字,或者编写适当的服务器。
  • 在初始双向通信阶段完成后,使长时间运行的流程分叉
您可以使用
os.fork()

我看不到任何进程正在运行

您看不到任何进程正在运行,因为子
python
进程立即退出。
Popen
参数不正确

要启动完全独立的流程,您可以使用或使用systemd/supervisord/etc:

#!/usr/bin/python25
import daemon
from long_process import main

with daemon.DaemonContext():
    main()
尽管在您的情况下,用正确的
Popen
参数启动子项可能就足够了:

with open(os.devnull, 'r+b', 0) as DEVNULL:
    p = Popen(['/usr/bin/python25', '/path/to/long_process.py'],
              stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT, close_fds=True)
time.sleep(1) # give it a second to launch
if p.poll(): # the process already finished and it has nonzero exit code
    sys.exit(p.returncode)
如果子进程不需要
python2.5
,那么可以使用
sys.executable
(使用与父进程相同的Python版本)


注意:代码在父进程中关闭
DEVNULL
,而不等待子进程完成(它对子进程没有影响)。

您能给出一个失败的最小示例吗?在一个简单的
python-c'导入子流程之后;subprocess.Popen([“sleep”,“60”])
ps的输出显示
sleep
在Python退出后仍能正常运行。您使用一个参数运行Python,
“nohup/usr/bin/python25…”
,它无法工作,因为
python
可执行文件将在名为nohup/usr/bin/…的文件中查找脚本,该文件不存在。而且,由于在没有读取管道内容的情况下将
stderr
指定为
PIPE
,因此永远看不到错误消息。丢失
nohup
&
,只需运行
subprocess.Popen([sys.executable,“/…/long_process.py]”)
。另外,除非你是认真的,否则不要将
stdin
stderr
指定为管道。
nohup
在从shell启动进程时最有意义。在您的
Popen
调用中,我看不到
shell=True
。回答得很好,进程由于
SIGPIPE
而终止是一个好问题。(在问题中的代码中,进程从未启动,但OP可能也尝试了其他因
SIGPIPE
而启动和停止的变体)它没有创建“完全独立的进程”(这是
python守护进程
包所做的)。也。虽然在简单的情况下,您的解决方案就足够了(您应该重定向到
os.devnull
child的stdin/stdout/stderr,以避免等待输入和/或到终端的虚假输出)。@user4815162342:它不会因为Python 2中的SIGPIPE而消亡(问题有标签)。以下是重定向之所以重要的一个示例:它可能允许父进程在其子进程完成其输出写入之前退出:请注意,
os.fork()
在这里使用
nohup
是毫无意义的。它只做了两件事:(1)禁用HUP传播,这对于非交互shell已经关闭,因此不需要进一步禁用;(2)如果stdin、stdout和stderr连接到终端,则重定向它们(您可以自己做这件事;
nohup.out 2>&1
,而您只做了nohup会做的完全相同的重定向)。就像@jfs的回答那样,完全不使用所有shell更有效。
with open(os.devnull, 'r+b', 0) as DEVNULL:
    p = Popen(['/usr/bin/python25', '/path/to/long_process.py'],
              stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT, close_fds=True)
time.sleep(1) # give it a second to launch
if p.poll(): # the process already finished and it has nonzero exit code
    sys.exit(p.returncode)