来自 Python 的 运行 命令,然后关闭

run command from Python and then close

我正在尝试构建一个小型 shell 应用程序,它 运行 是来自 GUI 应用程序的命令。当我按下 "off" 按钮时,该命令的控制台应该关闭。我有两个问题:

  1. 当我 运行 命令时,命令 运行ning 在与我的 Python 脚本相同的控制台上。如何在新控制台中打开命令?

  2. 如何停止命令?我的意思是,如果命令在与 GUI 相同的进程中工作,我可以只使用 exit(),但整个程序将被终止。

到目前为止,这是我的代码:

from tkinter import *
import subprocess
import os

top = Tk()

def turnOn():
    p = subprocess.Popen("ping whosebug.com")

def turnOff():
    pass
    #should i do: p.close() of something?

on = Button(top, text = "on", command = turnOn)
off = Button(top, text = "off", command = turnOff)

on.grid()
off.grid()
top.mainloop()

您可以通过调用子进程的 .terminate 方法来停止命令。这是一个使用全局变量存储 Popen 对象的粗略示例;最好将 GUI 包装在 class 中,并将 proc 存储为 class.

的实例属性
import tkinter as tk
import subprocess

top = tk.Tk()

proc = None

def turnOn():
    global proc
    if proc is None:
        print('Starting ping')
        proc = subprocess.Popen(["ping", "example.com"])

def turnOff():
    global proc
    if proc is not None:
        print('Stopping ping')
        proc.terminate()
        proc = None

on = tk.Button(top, text = "on", command = turnOn)
off = tk.Button(top, text = "off", command = turnOff)

on.grid()
off.grid()

top.mainloop()

if proc is None: 行阻止 ping 命令在已经 运行 时重新启动。

1)when i run command, the cmd command is running on the same cmd that my pythoh script is work. how can i open the the command in another cmd window?

我假设您是想说您需要 运行 另一个进程 shell。您应该使用子流程函数的 "shell" 参数:

subprocess.call(cmd, shell=True)

如果您只需要另一个命令提示符 window,只需打开另一个 Windows cmd。

2)how can i stop the command? i mean like if the command is work on the same window that the gui work i can just use in exit(), but then the all programm will be stop.

子进程 Popen 对象有一个终止方法。您可以将此称为发送 SIGTERM 信号,但并不总是可靠的。因此,根据您的 OS 和流程的性质,有多种选择 (一点注意:Popen 对象有一个 pid 属性和进程 pid):

  • os.kill(pid, signal) => 在 Posix/Windows OS
  • 上杀死一个简单进程
  • os.killpg(pgid, signal) => 在 Unix OS
  • 上作为一个组终止一个进程
  • subprocess.Popen("taskkill /F /T /PID %i" % pid, shell=True) => 终止进程 windows

信号是 posix/windows 信号,取决于 OS。 IE。 :

os.killpg(self.pid, signal.SIGKILL)     # Posix
os.kill(self.pid, signal.CTRL_C_EVENT)  # Windows

os.kill 调用在 Windows 上并不总是可靠。这就是原因 使用第三个选项。