Python运行守护进程子进程&读取标准输出 [英] Python Run a daemon sub-process & read stdout

查看:47
本文介绍了Python运行守护进程子进程&读取标准输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要运行一个程序并将其输出收集到标准输出.这个程序(socat)需要在python脚本运行期间在后台运行.Socat 在运行后处于 dameon 模式,但首先它会向 stdout 输出一些行,我的脚本其余部分需要这些行.

I need to run a program and gather its output to stdout. This program (socat) needs to run in the background for the duration of the python script. Socat sits in dameon mode once it's run, but first it outputs some lines to stdout that I need for the rest of my script.

命令:socat -d -d PTY:PTY:

输出:

2011/03/23 21:12:35 socat[7476] N PTY is /dev/pts/1
2011/03/23 21:12:35 socat[7476] N PTY is /dev/pts/2
2011/03/23 21:12:35 socat[7476] N starting data transfer loop with FDs [3,3] and [5,5]

...

我基本上想在我的程序开始时运行它并让它一直运行到脚本终止,但我需要将两个/dev/pts/X 名称读入 python.

I basically want to run that at the start of my program and leave it running till script termination, but I need to read the two /dev/pts/X names into python.

谁能告诉我怎么做?

我想出了这个只是挂起,我猜是因为它阻止了子进程终止.

I came up with this which just hangs, I guess because it's blocking for the child process to terminate.

#!/usr/bin/python
from subprocess import Popen, PIPE, STDOUT

cmd = 'socat -d -d PTY: PTY: &'

p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
output = p.stdout.read()

# Process the output 
print(output)

感谢您的帮助

似乎它可能会写入标准错误,但脚本仍然会在有和没有 & 的情况下挂起.甚至从 stderr 读取.

Seems it may write to stderr, but the script still just hanges with and without the & even reading from stderr.

推荐答案

#!/usr/bin/python
from subprocess import Popen, PIPE, STDOUT
import pty
import os

cmd = 'socat -d -d PTY: PTY:'

master, slave = pty.openpty()

p = Popen(cmd, shell=True, stdin=PIPE, stdout=slave, stderr=slave, close_fds=True)
stdout = os.fdopen(master)
print stdout.readline()
print stdout.readline()

您的版本有两个问题.首先,您不加参数地调用 read 这意味着它将尝试读取所有内容.但是因为 socat 不会终止,所以它永远不会决定它已经读取了所有内容.通过使用 readline,python 只会读取直到找到换行符.根据我对您的问题的理解,这正是您所需要的.

There are two problems with your version. Firstly, you call read without argument which means it will attempt to read everything. But since socat doesn't terminate, it never decides that it has read everything. By using readline, python only reads until it finds a newline. From my understanding of your problem that is what you need.

第二个问题是C标准库会在管道上缓冲输出.我们通过使用 openpty() 函数创建一个 pty 并将其传递给子进程的 stdout 和 stderr 来解决这个问题.我们使用 fdopen 将该文件描述符变成一个常规的 python 对象,然后我们摆脱了缓冲.

The second problem is that the C standard library will buffer outputs on pipes. We solve that by creating a pty with the openpty() function and passing it to both stdout and stderr of the subprocess. We use fdopen to make that file descriptor into a regular python object and we get rid of the buffering.

我不知道你在用 socat 做什么,但我想知道它是否可以通过使用 pty 模块来代替.您正在将一个 pty 复制到另一个 pty,而 openpty 正在创建一对 pty.也许你可以直接使用它们?

I don't know what you are doing with the socat, but I wonder whether it could replaced by using the pty module. You are copying one pty to another, and openpty is creating a pair of ptys. Perhaps you can use those directly?

这篇关于Python运行守护进程子进程&读取标准输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆