我正在使用以下代码将一些输入传递给具有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()调用分隔,不会改变任何东西.
我想执行一个进程,以秒为单位将执行时间限制为一些超时并获取进程产生的输出.我想在windows,linux和freebsd上做这个.
我试过以三种不同的方式实现它:
cmd - 没有超时和subprocess.PIPE用于输出捕获.
行为:按预期运行但不支持超时,我需要超时...
cmd_to - 使用timeout和subprocess.PIPE进行输出捕获.
BEHAVIOR:当输出> = 2 ^ 16字节时阻止子进程执行.
cmd_totf - 使用timeout和tempfile.NamedTemporaryfile进行输出捕获.
行为:按预期运行,但在磁盘上使用临时文件.
这些可在下面获得进一步检查.
从下面的输出中可以看出,当使用子处理时,超时代码会阻止子进程的执行.PIPE和子进程的输出是> = 2 ^ 16字节.
子进程文档说明在调用process.wait()和使用subprocessing.PIPE时这是预期的,但是在使用process.poll()时没有给出警告,那么这里出了什么问题?
我在cmd_totf中有一个使用tempfile模块的解决方案,但权衡是它将输出写入磁盘,这是我真正想要避免的.
所以我的问题是:
用于生成一堆输出的脚本('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模块花费相对较长时间的linux二进制文件时,这会释放GIL吗?
我想并行化一些从命令行调用二进制程序的代码.是否更好地使用线程(通过threading和a multiprocessing.pool.ThreadPool)或multiprocessing?我的假设是,如果subprocess发布GIL,那么选择该threading选项会更好.
这个问题 - 如何从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上的内容?
我在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的子进程调用的进程的输出.
我以为我可以将我的文件类对象作为命名参数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) 我正在编写一个与工作流管理器一起使用的包装类.我想以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 为 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 会话,我可以通过管道与之进行通信。
文件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中实现了一个非阻塞读取器,我需要提高它的效率.
背景:我需要从一个子进程(从Popen()开始)读取大量输出并传递给另一个线程.读取该子进程的输出不得阻塞超过几毫秒(最好是读取可用字节所需的时间很短).
目前,我有一个实用程序类,它接受文件描述符(stdout)和超时.我select()和readline(1)直到三件事情之一碰巧:
然后我将缓冲的文本返回给调用方法,该方法用它来完成.
现在,对于真正的问题:因为我正在阅读如此多的输出,我需要提高效率.我想通过询问文件描述符有多少字节待处理来做到这一点readline([that many bytes]).它应该只是传递东西,所以我实际上并不关心新线,或者即使有任何.我可以问一下文件描述符可以读取多少字节,如果可以,怎么做?
我已经做了一些搜索,但是我很难找到要搜索的内容,更不用说是否可能了.
即使是正确方向的一点也会有所帮助.
注意:我正在开发Linux,但这对于"Pythonic"解决方案来说无关紧要.