【问题标题】:Why I cannot run shell commands via PS gui in Python?为什么我不能在 Python 中通过 PS gui 运行 shell 命令?
【发布时间】:2020-10-30 11:14:40
【问题描述】:

我正在尝试通过 python 的 gui (PySimple) 在终端中运行 avrdude 命令...它没有返回任何错误,但是它也不起作用。那么问题来了:

  1. 为什么它不起作用?要么,如果我想运行脚本——txt 文件或简单的 shell 命令,例如“ls”,请查看代码。
  2. 我怎样才能看到python里面的shell终端?这将有助于我了解发生了什么...

最初的想法。

import PySimpleGUI as sg
import subprocess
    
layout = [
    [sg.Text('Filename')],
    [sg.Input('', key='filename'), sg.FileBrowse()],
    [sg.Button('Ok'), sg.Button('Cancel')],
]
    
window = sg.Window('Test', layout)
    
while True:
    event, values = window.read()
    if event in ('Exit', None): break
    
    #print(event, values)
    
    if event == 'Ok':
        print(event, values)
        #run the terimanl code???
        #subprocess.run('/Users/mu234/Desktop/myScript_sm-ir.txt')
        subprocess.run('ls') 
    
window.close()

在您的 cmets(例如,MikeyB 等)和我的几次讨论、谷歌搜索之后,我已经移动了一点,并将在此处发布尝试如何解决这个问题,但是,当文件被处理时,不知怎的,整个程序都不行了……

import subprocess
import sys
import PySimpleGUI as sg

sg.theme('Dark Blue 4')

def main():
    layout = [
                [sg.Output(size=(110,40), background_color='black', text_color='white')],
                ##[sg.T('Prompt> '), sg.Input(key='-IN-', do_not_clear=False)], #type in prompt
                                [sg.Text('Choose the script you want to process')],
                                [sg.Input('', key='filename'), sg.FileBrowse()], #choose a file you want to process with the script
                                #[sg.Button('Process'), sg.Button('Cancel'), sg.Button('Exit')]], #process the chosen file, else exit
                [sg.Button('Process', bind_return_key=True), sg.Button('Exit')] ]

    window = sg.Window('Realtime Shell Command Output', layout)

    while True:             # Event Loop
        event, values = window.read()
        # print(event, values)
        if event in (sg.WIN_CLOSED, 'Exit'):
            break
        elif event == 'Process':
            #print(event, values)
                      
            runCommand(cmd=values['filename'], window=window)          
    window.close()


def runCommand(cmd, timeout=None, window=None):
    nop = None
    
    """ run shell command
    @param cmd: command to execute
    @param timeout: timeout for command execution
    @param window: the PySimpleGUI window that the output is going to (needed to do refresh on)
    @return: (return code from command, command output)
    """
    
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = ''
    for line in p.stdout:
        line = line.decode(errors='replace' if (sys.version_info) < (3, 5) else 'backslashreplace').rstrip()
        output += line
        print(line)
        window.refresh() if window else nop        # yes, a 1-line if, so shoot me
    retval = p.wait(timeout)
    return (retval, output)

main()

图形用户界面在那里,用户可以轻松地浏览和选择文件(脚本)并处理它,但是,不知何故脚本被卡住了。例如,这是我在 GUI 中得到的输出:

/Users/mu234/Desktop/myScript_am-ir.txt:第 3 行:--:找不到命令

/Users/mu234/Desktop/myScript_am-ir.txt:第 5 行:avrdude:命令不 找到了

/Users/mu234/Desktop/myScript_am-ir.txt:第 9 行:--:找不到命令

/Users/mu234/Desktop/myScript_am-ir.txt:第 11 行:avrdude:命令不 找到了

/Users/mu234/Desktop/myScript_am-ir.txt:第 14 行:--:命令不是 找到了

/Users/mu234/Desktop/myScript_am-ir.txt:第 16 行:avrdude:命令不 找到了

有效吗?

简而言之,它不能胜任这项工作。我在想权限有问题吗?我在 OSX 上。 ,我猜问题出在访问文件的权限...脚本并在脚本中执行命令?一般来说,该脚本只有几行代码(查看此处了解可能的命令:https://www.cs.ou.edu/~fagg/classes/general/atmel/avrdude.pdf)。

例如,如果只使用“echo ...”,它可以正常工作,正如您在上面的打印中看到的那样...无论如何,请查看代码并评论可能出现的问题。

【问题讨论】:

  • 有许多演示程序位于 PySimpleGUI GitHub 中,展示了如何从 PySimpleGUI 程序中启动脚本、获取输出,然后选择性地显示在您的窗口中。一个值得研究的好方法是 Demo_Script_Launcher_Realtime_Output,它使用 Popen 而不是运行。
  • 谢谢,这是很有价值的输入,得到了您所指的脚本,并且它有效,但是,我需要更多时间来研究这个并将两者放在一起:)
  • 请不要在答案中发布附录或额外问题。如果您有关于这个问题的更多信息,请edit它。否则,请提出一个新问题

标签: python shell pysimplegui avrdude


【解决方案1】:

当您使用subprocess.run(command) 时,它会将输出写入 sys.stdout(Linux 上的 /dev/stdout),这基本上是终端/控制台的输出。

你可能想要做更多这样的事情

from subprocess import Popen, PIPE

proc = Popen(command.split(' '), stdin=PIPE, stdout=PIPE, stderr=PIPE) # spawns the process, but redirects stdin, stdout, and stderr from the terminal/console
proc_output = proc.communicate()[0].decode('utf-8') # reads stdout output and stores string into a variable
# Do something with proc_output in your GUI

我还在您的注释行中看到,您正在尝试使用 .txt 文件生成进程?如果那是一个脚本,你会想要更改文件扩展名(在 Windows 上需要,对于 linux,shebangs 就足够了)

附:您可以简单地从脚本中导入函数并从不同的脚本/文件中调用这些函数,而不是使用 subprocess 模块来运行脚本。

Google 和文档是您的朋友

【讨论】:

  • 为快速回复和信息干杯。不太确定“而不是使用...”是什么意思?脚本背后的想法是将所有功能作为一个可以快速执行的文件,尤其是使用 GUI,只需用鼠标按一下...
  • 如果您的程序只是一个简单的文件启动器,则无需注意,当我仔细观察时似乎确实如此。由于我的解决方案回答了您的问题,也许您可​​以将其标记为正确答案? (您以后可以随时更改)
  • 谢谢,不知何故它不起作用,我得到的错误,可能是我如何放置代码的错,对不起,这是新的......:好的{'filename':'/Users/mu234 /Desktop/myScript_sm-ir_copy.sh', 'Browse': '/Users/mu234/Desktop/myScript_sm-ir_copy.sh'} 回溯(最后一次调用):文件“/Users/mu234/Desktop/Python delam/run file.py”,第 28 行,在 proc = Popen(command.split(' '), stdin=PIPE, stdout=PIPE, stderr=PIPE) NameError: name 'command' is not defined
  • 你在重塑subprocess.run(),很糟糕。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-02
  • 2015-04-02
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
相关资源
最近更新 更多