相关疑难解决方法(0)

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 Popen.communicate()内存限制的替代方案?

我有以下大量的Python代码(运行v2.7)导致在MemoryError处理大(几GB)文件时抛出异常:

myProcess = Popen(myCmd, shell=True, stdout=PIPE, stderr=PIPE)
myStdout, myStderr = myProcess.communicate()
sys.stdout.write(myStdout)
if myStderr:
    sys.stderr.write(myStderr)
Run Code Online (Sandbox Code Playgroud)

在阅读文档时Popen.communicate(),似乎有一些缓冲:

注意读取的数据缓冲在内存中,因此如果数据大小很大或不受限制,请不要使用此方法.

有没有办法禁用此缓冲,或强制缓存在进程运行时定期清除?

我应该在Python中使用什么替代方法来运行将千兆字节数据流式传输到的命令stdout

我应该注意,我需要处理输出和错误流.

python memory stream popen

19
推荐指数
2
解决办法
5238
查看次数

从python中运行交互式命令

我有一个脚本,我想在python(2.6.5)中运行,遵循以下逻辑:

  • 提示用户输入密码.看起来像("输入密码:")(*注意:输入不回显到屏幕)
  • 输出无关信息
  • 提示用户回复("Blah Blah filename.txt blah blah(Y/N)?:")

最后一个提示行包含我需要解析的文本(filename.txt).提供的响应无关紧要(只要我可以解析该行,程序实际上可以在不提供响应的情况下退出)

我的要求有点类似于在python脚本中包装交互式命令行应用程序,但是那里的响应看起来有点令人困惑,即使OP提到它不适合他,我仍然会挂起.

通过环顾四周,我得出的结论subprocess是这样做的最佳方式,但我遇到了一些问题.这是我的Popen系列:

p = subprocess.Popen("cmd", shell=True, stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
  • 当我打电话给read()readline()打开时stdout,提示是打印机到屏幕并挂起.

  • 如果我叫write("password\n")stdin,提示被写入屏幕,它挂起.write()未写入文本(我没有光标移动新行).

  • 如果我调用p.communicate("password\n"),与write()相同的行为

我在这里寻找一些关于输入的最佳方式的想法,stdin如果你感觉很慷慨,可能如何解析输出中的最后一行,尽管我最终可能会想到这一点.

python stdin subprocess interactive stdout

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

Python子进程并行

我希望能够并行运行多个进程,并且能够随时使用stdout.我该怎么办?我是否需要为每个subprocess.Popen()呼叫运行线程,什么?

python subprocess

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

Python C程序子进程挂起"for line in iter"

好的,我试图从python脚本运行一个C程序.目前我正在使用测试C程序:

#include <stdio.h>

int main() {
while (1) {
    printf("2000\n");
    sleep(1);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)

模拟我将要使用的程序,它不断地从传感器获取读数.然后我试图"2000"从C程序读取输出(在这种情况下)与python中的子进程:

#!usr/bin/python
import subprocess

process = subprocess.Popen("./main", stdout=subprocess.PIPE)
while True:
    for line in iter(process.stdout.readline, ''):
            print line,
Run Code Online (Sandbox Code Playgroud)

但这不起作用.从使用print语句开始运行该.Popen行然后等待for line in iter(process.stdout.readline, ''):,直到我按下Ctrl-C.

为什么是这样?这正是我见过的大多数示例都是他们的代码,但它没有读取文件.

编辑:

有没有办法让它只在有东西被阅读时才能运行?

c python subprocess hang

17
推荐指数
2
解决办法
5446
查看次数

在线程中使用Popen会阻止每个传入的Flask-SocketIO请求

我有以下情况:我在socketio服务器上收到请求.我回答它(socket.emit(..))然后在另一个线程中启动一些计算负载很重的东西.

如果繁重的计算是由subprocess.Popen(使用subprocess.PIPE)引起的,它会完全阻止每个传入的请求,只要它正在被执行,尽管它发生在一个单独的线程中.

没问题 - 在这个线程中,建议异步读取子进程的结果,缓冲区大小为1,以便在这些读取之间,其他线程有机会做某事.不幸的是,这对我没有帮助.

我也已经monkeypatched eventlet和工作正常-只要我不使用subprocess.Popensubprocess.PIPE在线程.

在此代码示例中,您可以看到它只在使用subprocess.Popen时发生subprocess.PIPE.当取消注释#functionWithSimulatedHeavyLoad()并反而评论functionWithHeavyLoad()一切都像魅力一样.

from flask import Flask
from flask.ext.socketio import SocketIO, emit
import eventlet

eventlet.monkey_patch()
app = Flask(__name__)
socketio = SocketIO(app)

import time
from threading  import Thread

@socketio.on('client command')
def response(data, type = None, nonce = None):
    socketio.emit('client response', ['foo'])
    thread = Thread(target = testThreadFunction)
    thread.daemon = True
    thread.start()

def testThreadFunction(): …
Run Code Online (Sandbox Code Playgroud)

python multithreading pipe popen flask

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

python子进程communication()块

我正在使用进程模块调用外部程序(plink.exe)来登录服务器; 但是当我呼叫通信来读取输出时,它就是阻塞.代码如下:

 import subprocess
 process = subprocess.Popen('plink.exe hello@10.120.139.170 -pw 123456'.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 print process.communicate() #block here
Run Code Online (Sandbox Code Playgroud)

我知道该块是因为plink.exe它仍在运行; 但我需要在子进程终止之前读取输出.反正有吗?

python subprocess blocking

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

使用python从子进程读取输出

上下文

我正在使用该subprocess模块从python启动进程.我希望能够在写入/缓冲后立即访问输出(stdout,stderr).

  • 该解决方案必须支持Windows 7.我也需要Unix系统的解决方案,但我怀疑Windows案例更难以解决.
  • 该解决方案应该支持Python 2.6.我目前仅限于Python 2.6,但仍然赞赏使用更高版本的Python的解决方案.
  • 解决方案不应使用第三方库.理想情况下,我会喜欢使用标准库的解决方案,但我愿意接受建议.
  • 解决方案必须适用于任何流程.假设无法控制正在执行的进程.

儿童过程

例如,假设我想运行一个名为counter.pyvia a 的python文件subprocess.内容counter.py如下:

import sys

for index in range(10):

    # Write data to standard out.
    sys.stdout.write(str(index))

    # Push buffered data to disk.
    sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

父流程

负责执行该counter.py示例的父进程如下:

import subprocess

command = ['python', 'counter.py']

process = subprocess.Popen(
    cmd,
    bufsize=1,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    ) 
Run Code Online (Sandbox Code Playgroud)

问题

使用该counter.py示例,我可以在流程完成之前访问数据.这很棒!这正是我想要的.但是,删除该sys.stdout.flush()调用会阻止在我想要的时间访问数据.这是不好的!这正是我不想要的.我的理解是flush()调用强制将数据写入磁盘,在将数据写入磁盘之前,它只存在于缓冲区中.请记住,我希望能够运行任何进程.我不希望这个过程执行这种刷新,但我仍然期望数据可以实时(或接近它).有没有办法实现这个目标?

关于父进程的快速说明.您可能会注意到我正在使用bufsize=0线路缓冲.我希望这会导致每行的磁盘刷新,但它似乎不会那样工作.这个论点如何运作?

您还会注意到我正在使用subprocess.PIPE.这是因为它似乎是在父进程和子进程之间生成IO对象的唯一值.我通过查看模块中的Popen._get_handles方法得出了这个结论subprocess(我在这里指的是Windows定义).有两个重要的变量,c2preadc2pwrite …

python buffer subprocess pipe flush

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

subprocess.Popen.stdout - 实时读取标准输出(再次)

同样,同样的问题.
原因是 - 阅读以下内容后仍然无法使其正常工作:

我的情况是我有一个用C编写的控制台应用程序,让我们在循环中采用这个代码:

tmp = 0.0;   
printf("\ninput>>"); 
scanf_s("%f",&tmp); 
printf ("\ninput was: %f",tmp); 
Run Code Online (Sandbox Code Playgroud)

它不断读取一些输入并写入一些输出.

我与它交互的python代码如下:

p=subprocess.Popen([path],stdout=subprocess.PIPE,stdin=subprocess.PIPE)
p.stdin.write('12345\n')
for line in p.stdout: 
    print(">>> " + str(line.rstrip())) 
    p.stdout.flush() 
Run Code Online (Sandbox Code Playgroud)

到目前为止,每当我读取表单时,p.stdout它总是等待,直到进程终止然后输出一个空字符串.我尝试了很多东西 - 但结果仍然相同.

我尝试过Python 2.6和3.1,但版本没关系 - 我只需要让它在某个地方工作.

python subprocess stdout popen

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

使用popen和专用的TTY Python运行交互式Bash

我需要在Python中使用它自己的专用TTY在一个单独的进程中运行一个交互式Bash实例(我不能使用pexpect).我使用了这个通常在类似程序中使用过的代码片段:

master, slave = pty.openpty()

p = subprocess.Popen(["/bin/bash", "-i"], stdin=slave, stdout=slave, stderr=slave)

os.close(slave)

x = os.read(master, 1026)

print x

subprocess.Popen.kill(p)
os.close(master)
Run Code Online (Sandbox Code Playgroud)

但是当我运行它时,我得到以下输出:

$ ./pty_try.py
bash: cannot set terminal process group (10790): Inappropriate ioctl for device
bash: no job control in this shell
Run Code Online (Sandbox Code Playgroud)

运行的Strace显示一些错误:

...
readlink("/usr/bin/python2.7", 0x7ffc8db02510, 4096) = -1 EINVAL (Invalid argument)
...
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7ffc8db03590) = -1 ENOTTY (Inappropriate ioctl for device)
...
readlink("./pty_try.py", 0x7ffc8db00610, 4096) = -1 EINVAL (Invalid argument)
Run Code Online (Sandbox Code Playgroud)

代码片段看起来很简单,Bash没有得到它需要的东西吗?这可能是什么问题?

python linux bash python-2.x tty

12
推荐指数
2
解决办法
7066
查看次数