相关疑难解决方法(0)

python中subprocess.PIPE上的非阻塞读取

我正在使用子进程模块启动子进程并连接到它的输出流(stdout).我希望能够在其标准输出上执行非阻塞读取.有没有办法让.readline非阻塞或在我调用之前检查流上是否有数据.readline?我希望这是可移植的,或至少在Windows和Linux下工作.

这是我现在如何做到的(.readline如果没有数据可用,则阻止它):

p = subprocess.Popen('myprogram.exe', stdout = subprocess.PIPE)
output_str = p.stdout.readline()
Run Code Online (Sandbox Code Playgroud)

python io subprocess nonblocking

477
推荐指数
15
解决办法
21万
查看次数

在进程运行时不断打印Subprocess输出

要从我的Python脚本启动程序,我使用以下方法:

def execute(command):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = process.communicate()[0]
    exitCode = process.returncode

    if (exitCode == 0):
        return output
    else:
        raise ProcessException(command, exitCode, output)
Run Code Online (Sandbox Code Playgroud)

因此,当我启动一个类似的过程时Process.execute("mvn clean install"),我的程序会一直等到过程结束,然后我才能获得程序的完整输出.如果我正在运行需要一段时间才能完成的过程,这很烦人.

我可以让我的程序逐行写入进程输出,通过在循环结束之前轮询进程输出或其他内容吗?

**[编辑]抱歉,在发布此问题之前我没有很好地搜索.线程实际上是关键.在这里找到一个示例,说明如何执行此操作:** 来自线程的Python Subprocess.Popen

python subprocess

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

从需要stdin的子进程实时打印stdout

这是一个跟进这个问题,但如果我想传递一个参数stdinsubprocess,我怎么能得到实时输出?这就是我现在拥有的; 我也尝试从模块替换Popen,这只会导致脚本挂起.callsubprocess

from subprocess import Popen, PIPE, STDOUT
cmd = 'rsync --rsh=ssh -rv --files-from=- thisdir/ servername:folder/'
p = Popen(cmd.split(), stdout=PIPE, stdin=PIPE, stderr=STDOUT)
subfolders = '\n'.join(['subfolder1','subfolder2'])
output = p.communicate(input=subfolders)[0]
print output
Run Code Online (Sandbox Code Playgroud)

在前一个我没有通过的问题stdin我被建议使用p.stdout.readline,那里没有任何空间来管道stdin.

附录:这适用于转移,但我只看到输出的结尾,我希望看到转移的细节发生时.

python subprocess

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

如何从`stdin`创建非阻塞连续读取?

我有一个进程,它是这样创建的:

p = subprocess.Popen(args   = './myapp',
                     stdin  = subprocess.PIPE,
                     stdout = subprocess.PIPE,
                     universal_newlines=True)
Run Code Online (Sandbox Code Playgroud)

后来,我试着写pstdin:

p.stdin.write('my message\n')
Run Code Online (Sandbox Code Playgroud)

myapp过程具有以下设置:

q = queue.Queue()
def get_input():
    for line in iter(sys.stdin.readline, ''):
        q.put(line)
    sys.stdin.close()

threading.Thread(name   = 'input-getter',
                 target = get_input).start()
Run Code Online (Sandbox Code Playgroud)

它正在尝试不断读取新行,如下所示:

try:
    print('input:', q.get_nowait())
except Empty:
    print('no input')
Run Code Online (Sandbox Code Playgroud)

不幸的是,子进程从不接收任何消息.当然,当我使用时:

p.communicate('my message\n')
Run Code Online (Sandbox Code Playgroud)

子进程临危消息,但正如所料,communicate方法关闭pstdin,所以没有更多的沟通正在进行.

python stdin subprocess nonblocking python-3.x

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

是否可以实时将python子流程的输出流式传输到网页?

在此先感谢您的帮助.我是python的新手,甚至更新的HTML.

过去几天我一直在尝试创建一个带有按钮的网页,以便在家庭服务器上执行任务.

目前我有一个python脚本生成一个带按钮的页面:

(See the simplified example below. removed code to clean up post)
Run Code Online (Sandbox Code Playgroud)

然后是一个python脚本,它运行所述命令并输出到iframe页面上:

(See the simplified example below. removed code to clean up post)
Run Code Online (Sandbox Code Playgroud)

这会在命令完成后输出整个完成的输出.我也尝试将-u选项添加到python脚本以运行它无缓冲.我也尝试过使用Python subprocess.如果它有助于我运行的命令类型apt-get update,以及其他用于移动文件和修复文件夹权限的Python脚本.

当从普通的Ubuntu服务器终端运行时它运行正常并实时输出,并且从我的研究中它应该在命令运行时输出.

谁能告诉我哪里出错了?我应该使用其他语言来执行此功能吗?

编辑简化示例:

初始页面:

#runcmd.html

<head>
    <title>Admin Tasks</title>
</head>

<center>
<iframe src="/scripts/python/test/createbutton.py" width="650" height="800" frameborder="0" ALLOWTRANSPARENCY="true"></iframe>
<iframe width="650" height="800" frameborder="0" ALLOWTRANSPARENCY="true" name="display"></iframe> 
</center>
Run Code Online (Sandbox Code Playgroud)

创建按钮的脚本:

cmd_page = '<form action="/scripts/python/test/runcmd.py" method="post" target="display" >' + '<label for="run_update">run updates</label><br>' + '<input align="Left" type="submit" value="runupdate" name="update" title="run_update">' + "</form><br>" …
Run Code Online (Sandbox Code Playgroud)

html python linux cgi web

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

标签 统计

python ×5

subprocess ×4

nonblocking ×2

cgi ×1

html ×1

io ×1

linux ×1

python-3.x ×1

stdin ×1

web ×1