Python正在读取Powershell脚本输出,使用子进程,希望逐行接收标准输出

2024-05-08 16:49:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在尝试从运行了一段时间的Powershell脚本中读取stdout,并根据正在ping的计算机数量生成输出

尝试将数据流式传输到文本框中,但经过所有尝试,我似乎只能让它一次给出所有输出

我一直试图不使用subprocess.communicate(),因为它似乎同时提供所有输出

代码如下:

from tkinter import *
import os
from subprocess import Popen, PIPE


window = Tk()
window.title( 'PowerShell Script Temp' )

frame = Frame(window)

fldrPath = r"C:/Users/firstname.lastname/Downloads/Powershell Development/Monthly Scans/"

listbox = Listbox(frame)
listbox.configure(width=50)

for name in os.listdir(fldrPath):
    listbox.insert('end', name)

def selection():
    fileList = listbox.curselection()
    for file in fileList:
        os.chdir(fldrPath)
        
        # Right here is the problematic section
        with Popen(["powershell.exe", '-File', fldrPath + '\\' + listbox.get(file)], stdout=PIPE, bufsize=1,
                   universal_newlines=True) as p:
            for line in p.stdout:
                output.insert('end', line)
                print(line, end='')   

output = Text(window, width=75, height=6, wrap=WORD, background="white")

btn = Button(frame, text='Run Script', command=selection)

btn.pack(side=RIGHT, padx=5)
listbox.pack(side=LEFT)
frame.pack(padx=30, pady=30)
output.pack(fill=BOTH, expand=1, padx=5, pady=5)

window.mainloop()

Doesn't filter line-by-line-在PS脚本完成后,只需将其全部吐出即可

我尝试了很多其他的方法:

尝试1

proc = subprocess.Popen(["powershell.exe", '-File', fldrPath + '\\' + listbox.get(file)], shell=True, stdout=PIPE)
    while proc.poll() is None:
         data = proc.stdout.readline()  # Alternatively proc.stdout.read(1024)
         print(data)
         text_box.insert('end', data)

尝试2

outpipe = subprocess.Popen(["powershell.exe", '-File', fldrPath + '\\' + listbox.get(file)],
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE).communicate()[0]
    text_box.insert("end", outpipe)

尝试3

with Popen(["powershell.exe", '-File', fldrPath + '\\' + listbox.get(file)], stdout=PIPE, bufsize=1,
         universal_newlines=True) as p, StringIO() as buf:
         for line in p.stdout:
             print(line, end='')
             buf.write(line)
         outpipe = buf.getvalue()
         output.insert('end', outpipe)

尝试4

proc = subprocess.Popen(["powershell.exe", '-File', fldrPath + '\\' + listbox.get(file)], shell=True,
                             stdout=subprocess.PIPE)
     while proc.poll() is None:
         p = proc.stdout.readline()
         output.insert('end', p)

事实上,我尝试了更多,但似乎记不起来了。有很多优点和缺点…现在我有点厌倦了😔. 我可以用我想要的方式把这个东西Print(),但不能流到文本框中;几乎就像.insert()太慢了

如果有人能把我引向正确的方向,我将不胜感激。我在这里尝试了几乎所有我能处理的类似线程,但似乎没有达到目的


Tags: stdoutlineprocwindowexefileendsubprocess
2条回答

请尝试以下操作:

command1 = "please type command whose output you want to achieve"
output1 = os.popen(command1).read()
print(output1)

不确定,伙计,但我希望这对你有用

Trying to get the data to stream into the text box, but after all I've tried, I only seem to be able to get it to give all the output at once.

此代码如下:

def selection():
    fileList = listbox.curselection()
    for file in fileList:
        os.chdir(fldrPath)
        
        # Right here is the problematic section
        with Popen(["powershell.exe", '-File', fldrPath + '\\' + listbox.get(file)], stdout=PIPE, bufsize=1,
                   universal_newlines=True) as p:
            for line in p.stdout:
                output.insert('end', line)
                print(line, end='') 

完成后,您可以看到它执行了什么。要更新它,您可以使用tkinter的after方法并检查给定时间内的更改。 就像这个例子一样

tkinter主循环的工作方式类似于this

     Start
       |
       |<                             +
       v                                                           ^
   Do I have    No[*]  Calculate how            Sleep for at       |
   work to do?    -> long I may sleep    -> most that much  ->|
       |                                        time               |
       | Yes                                                       |
       |                                                           |
       v                                                           |
   Do one callback                                                 |
       |                                                           |
       +                             -+

另一项建议是使用另一个thread。 你也应该阅读.communicate()的答案here

相关问题 更多 >