python中stdin.write_python子进程多个stdin.write和stdout.read

Thanks for taking time to answer the question. I am playing around with Python 3.4 and I have two simple python programs. One, a program called test.py that takes a user input and prints something.

while True:

print("enter something...")

x = input()

print(x)

time.sleep(1)

To send input to this program, I have another program that uses subprocess:

from subprocess import Popen, PIPE

cat = Popen('python test.py', shell=True, stdin=PIPE, stdout=PIPE)

cat.stdin.write("hello, world!\n")

cat.stdin.flush()

print(cat.stdout.readline())

cat.stdin.write("and another line\n")

cat.stdin.flush()

print(cat.stdout.readline())

However when I run the above program, I get an error:

enter something...

hello, world!

Traceback (most recent call last):

File "/opt/test.py", line 9, in

x = input()

EOFError: EOF when reading a line

Exception ignored in: <_io.textiowrapper name="<stdout>" mode="w" encoding="UTF-8">

BrokenPipeError: [Errno 32] Broken pipe

And if I replace test.py with a standard linux command like 'cat', things work as expected.

Is there any way I send multiple stdin writes and read multiple stdout back?

解决方案

Your specific issue might be caused by a python version mismatch (you think your code is executed using Python 3 while actually it might be executed using Python 2). The second issue (EOFError) is expected: either catch it in the child script or provide a signal for the child to exit (I use an empty line for that in the code example below).

Here's a Python 3 code that fails loudly on Python 2:

#!/usr/bin/env python3

import sys

from subprocess import Popen, PIPE

with Popen([sys.executable, '-u', 'test.py'], stdin=PIPE, stdout=PIPE,

universal_newlines=True, bufsize=1) as cat:

for input_string in ["hello, world!", "and another line", ""]:

print(input_string, file=cat.stdin, flush=True)

print(cat.stdout.readline(), end='')

Note:

sys.exectable is the current python executable (Python 3 in this case)

universal_newlines=True enables the text mode (otherwise, cat.stdin and cat.stdout work with bytes, not strings)

the with-statement closes the pipes and waits for the child process to exit.

And here's the corresponding test.py:

#!/usr/bin/env python3

import time

while True:

x = input("enter something...")

if not x: # exit if the input is empty

break

print(x)

time.sleep(1)

Output

enter something...hello, world!

enter something...and another line

enter something...

Note: there is no new line after "enter something..."

If the input is finite and it doesn't depend on the output then you could pass it all at once:

#!/usr/bin/env python3

import sys

from subprocess import check_output

output = check_output([sys.executable, 'test.py'],

input="\n".join(["hello, world!", "and another line"]),

universal_newlines=True)

print(output, end='')

This version requires that the child handles EOF properly:

#!/usr/bin/env python3

import time

while True:

try:

x = input("enter something...")

except EOFError:

break # no more input

print(x)

time.sleep(1)

The output is the same (as shown above).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
H.264是一种高效的视频编解码标准,常被用于实时视频传输。实现H.264视频推流和接收可以使用Python的OpenCV库和FFmpeg工具。 推流端: 1. 导入OpenCV库和FFmpeg工具,使用OpenCV库读取本地视频文件,打开视频流。 ```python import cv2 import subprocess # 打开视频文件 cap = cv2.VideoCapture('test_video.mp4') # 获取视频帧率 fps = int(cap.get(cv2.CAP_PROP_FPS)) # 设置视频编码器为H.264 fourcc = cv2.VideoWriter_fourcc(*'H264') # 创建输出视频流 output = cv2.VideoWriter('udp://127.0.0.1:1234', fourcc, fps, (640, 480)) ``` 2. 使用FFmpeg工具将视频流推送到目标地址。 ```python # 启动FFmpeg进程 cmd = 'ffmpeg -i - -vcodec copy -f mpegts udp://127.0.0.1:1234' p = subprocess.Popen(cmd.split(), stdin=subprocess.PIPE) # 推流 while True: ret, frame = cap.read() if ret: output.write(frame) p.stdin.write(frame.tostring()) else: break # 关闭FFmpeg进程和视频流 p.stdin.close() output.release() cap.release() ``` 接收端: 1. 导入OpenCV库和FFmpeg工具,使用FFmpeg工具接收视频流,并将其转换为OpenCV的Mat格式。 ```python import cv2 import subprocess # 启动FFmpeg进程 cmd = 'ffmpeg -i udp://127.0.0.1:1234 -f rawvideo -pix_fmt bgr24 -' p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) # 接收视频流 while True: # 读取视频帧 raw_frame = p.stdout.read(640*480*3) if len(raw_frame) != 640*480*3: break # 转换为OpenCV的Mat格式 frame = np.frombuffer(raw_frame, np.uint8).reshape((480, 640, 3)) # 显示视频帧 cv2.imshow('frame', frame) cv2.waitKey(1) # 关闭FFmpeg进程和窗口 p.stdout.close() cv2.destroyAllWindows() ``` 以上代码仅供参考,实际使用时需要根据具体情况进行修改。同时需要注意的是,H.264视频编解码需要较高的计算资源,推荐在较高配置的设备上进行测试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值