相关疑难解决方法(0)

从subprocess.communicate()读取流输入

我正在使用Python subprocess.communicate()来从一个运行大约一分钟的进程中读取stdout.

如何stdout以流式方式打印出该流程的每一行,以便我可以看到生成的输出,但在继续之前仍然阻止流程终止?

subprocess.communicate() 似乎立刻提供所有输出.

python subprocess

75
推荐指数
3
解决办法
7万
查看次数

合并Python脚本的子进程'stdout和stderr,同时保持它们可区分

我想将python脚本的子进程'stdout和stdin指向同一个文件.我不知道的是如何使两个来源的线条区分开来?(例如,带有感叹号的stderr行前缀.)

在我的特定情况下,不需要对子进程进行实时监视,执行的Python脚本可以等待其执行结束.

python subprocess stdout stderr

32
推荐指数
4
解决办法
2万
查看次数

Python在保留顺序的同时分别从子进程stdout和stderr读取

我有一个python子进程,我正在尝试从中读取输出和错误流.目前我有它的工作,但我只能在读完stderr之后阅读stdout.这是它的样子:

process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout_iterator = iter(process.stdout.readline, b"")
stderr_iterator = iter(process.stderr.readline, b"")

for line in stdout_iterator:
    # Do stuff with line
    print line

for line in stderr_iterator:
    # Do stuff with line
    print line
Run Code Online (Sandbox Code Playgroud)

如您所见,stderrfor循环在stdout循环完成之前无法启动.如何修改它以便能够以正确的顺序读取这两行?

澄清:我仍然需要能够判断一条线是否来自stdout或者stderr因为我的代码中它们的处理方式不同.

python subprocess stdout stderr

29
推荐指数
5
解决办法
2万
查看次数

Python子进程readlines()挂起

我尝试完成的任务是流式传输ruby文件并打印出输出.(注意:我不想一次打印出所有内容)

main.py

from subprocess import Popen, PIPE, STDOUT

import pty
import os

file_path = '/Users/luciano/Desktop/ruby_sleep.rb'

command = ' '.join(["ruby", file_path])

master, slave = pty.openpty()
proc = Popen(command, bufsize=0, shell=True, stdout=slave, stderr=slave, close_fds=True)     
stdout = os.fdopen(master, 'r', 0)

while proc.poll() is None:
    data = stdout.readline()
    if data != "":
        print(data)
    else:
        break

print("This is never reached!")
Run Code Online (Sandbox Code Playgroud)

ruby_sleep.rb

puts "hello"

sleep 2

puts "goodbye!"
Run Code Online (Sandbox Code Playgroud)

问题

流文件工作正常.hello/goodbye输出以2秒延迟打印.正如脚本应该工作.问题是readline()最后会挂起而永不退出.我从未到过最后一个印刷品.

我知道有很多这样的问题,这里有一个stackoverflow但是没有它们让我解决问题.我不是那个整个子流程的东西,所以请给我一个更实际/具体的答案.

问候

编辑

修复意外的代码.(与实际错误无关)

python subprocess

23
推荐指数
2
解决办法
2万
查看次数

Subprocess.Popen:将stdout和stderr克隆到终端和变量

是否可以修改以下代码以从'stdout'和'stderr'打印输出:

  • 印在终端上(实时),
  • 最后存储在outerrs变量中?

代码:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import subprocess

def run_cmd(command, cwd=None):
    p = subprocess.Popen(command, cwd=cwd, shell=False,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    outs, errs = p.communicate()
    rc = p.returncode
    outs = outs.decode('utf-8')
    errs = errs.decode('utf-8')

    return (rc, (outs, errs))
Run Code Online (Sandbox Code Playgroud)

感谢@unutbu,特别感谢@ jf-sebastian,最终功能:

#!/usr/bin/python3
# -*- coding: utf-8 -*-


import sys
from queue import Queue
from subprocess import PIPE, Popen
from threading import Thread


def read_output(pipe, funcs):
    for line in iter(pipe.readline, b''):
        for func in funcs: …
Run Code Online (Sandbox Code Playgroud)

python subprocess popen python-3.x

22
推荐指数
2
解决办法
6034
查看次数

Python子进程将子输出到文件和终端?

我正在运行一个脚本,通过使用执行许多可执行文件

subprocess.call(cmdArgs,stdout=outf, stderr=errf)
Run Code Online (Sandbox Code Playgroud)

when outf/ errf是None或文件描述符(stdout/的不同文件stderr).

有什么方法可以执行每个exe,以便将stdout和stderr一起写入文件和终端?

python subprocess parent

16
推荐指数
1
解决办法
6764
查看次数

在 python 中将输出捕获为 tty

我有一个需要 tty (如 stdin 和 stderr)的可执行文件,并且希望能够测试它。我想输入 stdin,并捕获 stdout 和 stderr 的输出,这是一个示例脚本:

# test.py
import sys
print("stdin: {}".format(sys.stdin.isatty()))
print("stdout: {}".format(sys.stdout.isatty()))
print("stderr: {}".format(sys.stderr.isatty()))
sys.stdout.flush()
line = sys.stdin.readline()
sys.stderr.write("read from stdin: {}".format(line))
sys.stderr.flush()
Run Code Online (Sandbox Code Playgroud)

我可以在没有 tty 的情况下运行它,但是它会被捕获.isatty并且每个都返回 False:

import subprocess
p = subprocess.Popen(["python", "test.py"], stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
p.stdin.write(b"abc\n")
print(p.communicate())
# (b'stdin: False\nstdout: False\nstderr: False\n', b'read from stdin: abc\n')
Run Code Online (Sandbox Code Playgroud)

我想捕获 stdout 和 stderr 并让所有三个返回 True - 作为 tty。

我可以用来pty制作 tty 标准输入:

import subprocess
m, s = pty.openpty()
p = subprocess.Popen(["python", "test.py"], …
Run Code Online (Sandbox Code Playgroud)

python subprocess popen tty

10
推荐指数
1
解决办法
4553
查看次数

subprocess.Popen :分离 stdout/stderr 但保持顺序

如何使用 subprocess.Popen 从命令获取输出,并为 stdout 和 stderr 提供单独的回调,但确保按照来自进程的行的顺序调用这些回调?

如果我不关心分离 STDOUT 和 STDERR 那么我可以这样做:

fd = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
line = fd.stdout.readline()
while line :
    callback( line )
    line = fd.stdout.readline()
Run Code Online (Sandbox Code Playgroud)

但是,如果我有stdoutCallbackstderrCallback,并且希望它们在适当的输出上调用,但按照与上述代码调用的顺序相同callback,我将如何去做呢?

python subprocess

5
推荐指数
1
解决办法
2115
查看次数

python流子进程stdout和stderr zip不起作用

已经有很多答案可以解决如何执行此常规操作,但是我的主要问题是为什么这种方法行不通?

我正在尝试从子进程“实时流式传输” stdout和stderr。我可以这样做:

import sys
import subprocess

def run_command(cmd):
    process = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

    for out in iter(process.stdout.readline, b''):
        print(out)

    for err in iter(process.stderr.readline, b''):
        print(err)

run_command(['echo', 'hello', 'world']) # should print hello world
run_command(['rm', 'blarg223'])  # Should print to stderr (file doesnt exist)
Run Code Online (Sandbox Code Playgroud)

这可以给我结果:

b'hello world\n'
b'rm: cannot remove \xe2\x80\x98blarg223\xe2\x80\x99: No such file or directory\n'
Run Code Online (Sandbox Code Playgroud)

但是,这会引起问题,因为它实际上仅实时输出标准输出,然后将所有错误打印到末尾。所以我想我可以使用以下方法解决此问题:

def run_command(cmd):
    process = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

    for out, err in zip(iter(process.stdout.readline, b''), iter(process.stderr.readline, b'')):
        print(out)
        print(b'Error: ' + err)
Run Code Online (Sandbox Code Playgroud)

但是,这不会产生任何输出。为什么使用zip无效?

python subprocess python-3.x

5
推荐指数
1
解决办法
158
查看次数

使用universal_newlines = True(使用bufsize = 1)和使用Popen的默认参数有什么区别?

我试图读取从Python调用的子进程的输出.为此我使用Popen(因为我不认为如果使用subprocess.call就可以管道stdout).

截至目前,我有两种方法可以做到这一点,在测试中,它似乎提供了相同的结果.代码如下:

with Popen(['Robocopy', source, destination, '/E', '/TEE', '/R:3', '/W:5', '/log+:log.txt'], stdout=PIPE) as Robocopy:
    for line in Robocopy.stdout:
        line = line.decode('ascii')
        message_list = [item.strip(' \t\n').replace('\r', '') for item in line.split('\t') if item != '']
        print(message_list[0], message_list[0])
    Robocopy.wait()
    returncode = Robocopy.returncode
Run Code Online (Sandbox Code Playgroud)

with Popen(['Robocopy', source, destination, '/E', '/TEE', '/R:3', '/W:5', '/log+:log.txt'], stdout=PIPE, universal_newlines=True, bufsize=1) as Robocopy:
    for line in Robocopy.stdout:
        message_list = [item.strip() for item in line.split('\t') if item != '']
        print(message_list[0], message_list[2])
    Robocopy.wait()
    returncode = Robocopy.returncode
Run Code Online (Sandbox Code Playgroud)

第一种方法不包括universal_newlines = True,因为文档说明这只有在universal_newlines …

python subprocess popen python-3.x

3
推荐指数
1
解决办法
7888
查看次数

如何让子进程按顺序获取标准输出和标准错误?

示例测试文件(print.py):

import sys
print('stdout')
print('stderr', file=sys.stderr)
Run Code Online (Sandbox Code Playgroud)

运行它的代码(x.py):

import subprocess
cmd = ['python', 'print.py']
print(subprocess.check_output(cmd, universal_newlines=True, stderr=subprocess.STDOUT))
Run Code Online (Sandbox Code Playgroud)

如果我从 shell 运行 print.py,它会首先打印 stdout。但是,如果我运行 x.py,它会首先打印 stderr。有什么办法可以让我以正确的顺序获得输出?

python subprocess

1
推荐指数
1
解决办法
99
查看次数

标签 统计

python ×11

subprocess ×11

popen ×3

python-3.x ×3

stderr ×2

stdout ×2

parent ×1

tty ×1