相关疑难解决方法(0)

pexpect无法通过1024个字符传递输入?

我正在使用以下代码将一些输入传递给具有pexpect的进程:

p = pexpect.spawn('cat', timeout=5.0 )
p.maxread = 5000
p.setecho(False) # prevent the process from echoing stdin back to us
INPUT_LEN = 1024
p.sendline('a'*INPUT_LEN)
print p.readline() # pexpect.TIMEOUT: Timeout exceeded in read_nonblocking().
Run Code Online (Sandbox Code Playgroud)

当INPUT_LEN <1024时,一切正常,但是对于> = 1024个字符,进程没有收到完整输入,导致在p.readline()上引发"pexpect.TIMEOUT"错误.

我尝试将输入分成小于1024个字符的片段,但这有同样的问题:

p = pexpect.spawn('cat', timeout=5.0 )
p.maxread = 5000
p.setecho(False)
INPUT_LEN = 1024
p.send('a'*1000)
p.sendline('a'*(INPUT_LEN-1000))
print p.readline() # pexpect.TIMEOUT: Timeout exceeded in read_nonblocking().
Run Code Online (Sandbox Code Playgroud)

有谁知道如何使用超过1024个字符的输入使pexpect工作?我试着查看源代码,但它似乎只是在调用os.write(...).

(作为旁注,我注意到当我从shell运行"cat"并尝试使用"Cmd + V"粘贴> = 1024个字符时发生相同的截断错误.但是,如果我运行"pbpaste,一切正常|猫".)

谢谢!

更新: 对"os.write()"的调用返回1025,表示写入成功,但os.read()返回"\ x07"(单个字符BEL),然后在下一次调用时挂起,导致超时.

将os.write()调用分为两个1024字节的write(),由os.fsync()调用分隔,不会改变任何东西.

python io macos expect pexpect

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

具有超时和大输出的python子进程(> 64K)

我想执行一个进程,以秒为单位将执行时间限制为一些超时并获取进程产生的输出.我想在windows,linux和freebsd上做这个.

我试过以三种不同的方式实现它:

  1. cmd - 没有超时和subprocess.PIPE用于输出捕获.

    行为:按预期运行但不支持超时,我需要超时...

  2. cmd_to - 使用timeout和subprocess.PIPE进行输出捕获.

    BEHAVIOR:当输出> = 2 ^ 16字节时阻止子进程执行.

  3. cmd_totf - 使用timeout和tempfile.NamedTemporaryfile进行输出捕获.

    行为:按预期运行,但在磁盘上使用临时文件.

这些可在下面获得进一步检查.

从下面的输出中可以看出,当使用子处理时,超时代码会阻止子进程的执行.PIPE和子进程的输出是> = 2 ^ 16字节.

子进程文档说明在调用process.wait()和使用subprocessing.PIPE时这是预期的,但是在使用process.poll()时没有给出警告,那么这里出了什么问题?

我在cmd_totf中有一个使用tempfile模块的解决方案,但权衡是它将输出写入磁盘,这是我真正想要避免的.

所以我的问题是:

  • 我在cmd_to做错了什么?
  • 有没有办法做我想要的,不使用临时文件/保持输出在内存中.

用于生成一堆输出的脚本('exp_gen.py'):

#!/usr/bin/env python
import sys
output  = "b"*int(sys.argv[1])
print output
Run Code Online (Sandbox Code Playgroud)

子处理周围包装器的三种不同实现(cmd,cmd_to,cmd_totf).Popen:

#!/usr/bin/env python
import subprocess, time, tempfile
bufsize = -1

def cmd(cmdline, timeout=60):
  """
  Execute cmdline.
  Uses subprocessing and subprocess.PIPE.
  """

  p = subprocess.Popen(
    cmdline,
    bufsize = bufsize,
    shell   = False,
    stdin   = subprocess.PIPE,
    stdout  = subprocess.PIPE,
    stderr  = subprocess.PIPE
  ) …
Run Code Online (Sandbox Code Playgroud)

python subprocess timeout

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

使用子进程模块是否释放python GIL?

当调用通过Python subprocess模块花费相对较长时间的linux二进制文件时,这会释放GIL吗?

我想并行化一些从命令行调用二进制程序的代码.是否更好地使用线程(通过threading和a multiprocessing.pool.ThreadPool)或multiprocessing?我的假设是,如果subprocess发布GIL,那么选择该threading选项会更好.

python multithreading subprocess gil python-multithreading

10
推荐指数
2
解决办法
3343
查看次数

在Windows上的os.pipe上读取非阻塞

这个问题 - 如何从os.pipe()读取而不被阻止?- 显示如何检查os.pipeLinux 是否有任何数据的解决方案,为此您需要将管道置于非阻塞模式:

import os, fcntl
fcntl.fcntl(thePipe, fcntl.F_SETFL, os.O_NONBLOCK)
Run Code Online (Sandbox Code Playgroud)

在Windows上我们有这个:

ImportError: No module named fcntl
Run Code Online (Sandbox Code Playgroud)

但是os.pipe有:

>>> os.pipe()
(3, 4)
Run Code Online (Sandbox Code Playgroud)

那么,是否可以进行非阻塞读取或窥视os.pipeWindows上的内容?

python windows pipe

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

通过Python与Windows控制台应用程序交互

我在Windows上使用python 2.5.我希望通过Popen与控制台进程进行交互.我目前有这小段代码:

p = Popen( ["console_app.exe"], stdin=PIPE, stdout=PIPE )
# issue command 1...
p.stdin.write( 'command1\n' )
result1 = p.stdout.read() # <---- we never return here
# issue command 2...
p.stdin.write( 'command2\n' )
result2 = p.stdout.read()
Run Code Online (Sandbox Code Playgroud)

我可以写stdin但无法从stdout读取.我错过了一步吗?我不想使用p.communicate("command")[0],因为它终止了进程,我需要随着时间的推移动态地与进程交互.

提前致谢.

python windows

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

换行子进程'stdout/stderr

我想捕获并显示我通过Python的子进程调用的进程的输出.

我以为我可以将我的文件类对象作为命名参数stdout和stderr传递

我可以看到它访问fileno属性 - 所以它正在对对象做一些事情.但是,write()永远不会调用该方法.我的方法是完全关闭还是我错过了什么?

class Process(object):
    class StreamWrapper(object):
        def __init__(self, stream):
            self._stream = stream
            self._buffer = []
        def _print(self, msg):
            print repr(self), msg
        def __getattr__(self, name):
            if not name in ['fileno']:
                self._print("# Redirecting: %s" % name)
            return getattr(self._stream, name)
        def write(self, data):
            print "###########"
            self._buffer.append(data)
            self._stream.write(data)
            self._stream.flush()
        def getBuffer(self):
            return self._buffer[:]
    def __init__(self, *args, **kwargs):
        print ">> Running `%s`" % " ".join(args[0])
        self._stdout = self.StreamWrapper(sys.stdout)
        self._stderr = self.StreamWrapper(sys.stderr)
        kwargs.setdefault('stdout', self._stdout)
        kwargs.setdefault('stderr', self._stderr)
        self._process = subprocess.Popen(*args, …
Run Code Online (Sandbox Code Playgroud)

python iostream subprocess stdout stderr

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

我可以拆分/合并subprocess.Popen的输出流吗?

我正在编写一个与工作流管理器一起使用的包装类.我想以subprocess.Popen某种方式记录应用程序的输出(通过执行的子进程):

  • stdout孩子应该去一个日志文件和stdout父母的,
  • stderr该子项应该转到不同的日志文件,但也应该转到stdout父项.

即所有来自孩子的输出应该最终合并stdout(比如subprocess.Popen(..., stderr=subprocess.STDOUT),因此我可以保留stderr来自包装器本身的日志消息.另一方面,孩子的流应该转到不同的文件以允许单独的验证.

我尝试使用"Tee"帮助程序类将两个流(stdout和日志文件)绑定在一起,以便Tee.write写入两个流.但是,这不能传递给Popen因为"subprocess"使用OS级函数进行编写(参见http://bugs.python.org/issue1631).

我当前的解决方案(下面的代码片段,主要是从这里调整)的问题是输出stdout可能不会以正确的顺序出现.

我怎么能克服这个?或者我应该使用完全不同的方法?(如果我坚持下面的代码,我如何选择一个字节数的值os.read?)

import subprocess, select, sys, os

call = ... # set this
process = subprocess.Popen(call, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
logs = {process.stdout: open("out.log", "w"), process.stderr: open("err.log", "w")}
done = {process.stdout: False, process.stderr: False}
while (process.poll() is None) or (not all(done.values())):
    ready = select.select([process.stdout, process.stderr], [], [])[0]
    for …
Run Code Online (Sandbox Code Playgroud)

python logging subprocess stream

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

使用 subprocess.Popen 执行 bash

我正在尝试使用 python 为 bash 会话编写一个包装器。我做的第一件事就是尝试生成一个 bash 进程,然后尝试读取它的输出。像这样:

from subprocess import Popen, PIPE
bash = Popen("bash", stdin = PIPE, stdout = PIPE, stderr = PIPE)
prompt = bash.stdout.read()
bash.stdin.write("ls\n")
ls_output = bash.stdout.read()
Run Code Online (Sandbox Code Playgroud)

但这不起作用。首先,在创建进程后从 bash 的标准输出读取失败,当我尝试写入标准输入时,出现管道损坏错误。我究竟做错了什么?

再次澄清一下,我对通过 bash 运行单个命令然后检索其输出不感兴趣,我希望在某个进程中运行一个 bash 会话,我可以通过管道与之进行通信。

python bash subprocess

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

我怎么知道我的子进程是否在等待我的输入?(在python3中)

文件sp.py:

#!/usr/bin/env python3
s = input('Waiting for your input:')
print('Data:' + s)
Run Code Online (Sandbox Code Playgroud)

文件main.py

import subprocess as sp
pobj = sp.Popen('sp.py',stdin=sp.PIPE,stdout=sp.PIPE,shell=True)
print(pobj.stdout.read().decode())
pobj.stdin.write(b'something...')
print(pobj.stdout.read().decode())
Run Code Online (Sandbox Code Playgroud)

main.py会阻塞第一个pobj.stdout.read(),因为sp.py在等我.
但是如果我想首先处理字符串'Waiting for you input:',我怎么知道sp.py是否在等我呢?
换句话说,我希望pobj.stdout.read()在sp.py等待(或因为time.sleep())而休眠时返回.

python subprocess python-3.x

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

如何(我可以)询问PIPE有多少字节可供阅读?

我在Python中实现了一个非阻塞读取器,我需要提高它的效率.

背景:我需要从一个子进程(从Popen()开始)读取大量输出并传递给另一个线程.读取该子进程的输出不得阻塞超过几毫秒(最好是读取可用字节所需的时间很短).

目前,我有一个实用程序类,它接受文件描述符(stdout)和超时.我select()readline(1)直到三件事情之一碰巧:

  1. 我读了一个换行符
  2. 我的超时(几毫秒)到期
  3. select告诉我那个文件描述符没什么可读的.

然后我将缓冲的文本返回给调用方法,该方法用它来完成.

现在,对于真正的问题:因为我正在阅读如此多的输出,我需要提高效率.我想通过询问文件描述符有多少字节待处理来做到这一点readline([that many bytes]).它应该只是传递东西,所以我实际上并不关心新线,或者即使有任何.我可以问一下文件描述符可以读取多少字节,如果可以,怎么做?

我已经做了一些搜索,但是我很难找到要搜索的内容,更不用说是否可能了.

即使是正确方向的一点也会有所帮助.

注意:我正在开发Linux,但这对于"Pythonic"解决方案来说无关紧要.

python subprocess popen nonblocking

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