Python脚本如何让os.popen()可以做到切换窗口呢

img


我在ubuntu20.04版本的终端运行python3 xxx.py脚本(已安装env虚拟环境),然后用pyautogui库的快捷键另外打开一个终端窗口,然后我想在第二个终端窗口ssh再输入一个Linux命令,我希望可以用os.popen()获取到输入Linux命令后的响应内容,但是Linux命令却作用到了第一个终端窗口,也就是脚本执行的窗口(绿色箭头所指向的终端窗口),我的预期是希望popen()可以作用在快捷键Ctrl+Alt+t打开的终端窗口,我该如何切换进程呢

img


我的ubuntu20.04一直装不上subprocess

参考GPT和自己的思路:在Linux系统中,一个窗口对应一个进程,而不同进程之间是不能直接交互的。因此,如果你想在第二个终端窗口中执行命令并获取其输出,你需要启动一个新的进程来执行命令。

你可以使用Python的subprocess模块来创建一个新的进程,并将命令的输出保存在一个变量中。然后,你可以在第一个终端窗口中使用pyautogui库发送一些信号,例如按下某些键或者输入一些特定的字符串,来使其失去焦点,然后在第二个终端窗口中执行命令。

下面是一个示例代码:

import subprocess
import pyautogui

# 在第二个终端窗口中执行的命令
cmd = "ls -l"

# 获取第二个终端窗口的句柄
# 在这里使用了pyautogui来模拟按键和输入,需要先将其置于前台
pyautogui.hotkey("ctrl", "alt", "t")
pyautogui.typewrite(cmd)
pyautogui.press("enter")

# 将第二个终端窗口设置为前台窗口,使其具有焦点
pyautogui.hotkey("alt", "tab")

# 创建一个新的进程来获取命令的输出
p = subprocess.Popen(
    cmd,
    shell=True,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)

# 获取命令的输出
output, error = p.communicate()

# 输出命令的输出和错误信息
print("Output:", output.decode())
print("Error:", error.decode())


在上面的代码中,我们首先使用pyautogui库模拟按下快捷键来打开一个新的终端窗口,并在其中输入了一个Linux命令。然后,我们使用pyautogui模拟按下alt+tab键将第二个终端窗口设置为前台窗口,使其具有焦点。
接下来,我们使用subprocess模块创建了一个新的进程来执行命令,并将命令的输出保存在了一个变量中。最后,我们输出了命令的输出和错误信息。

“Devil组”引证GPT后的撰写:

  • 用xdotool来实现在Python脚本中切换窗口的操作。xdotool是一个命令行工具,可以通过命令行模拟键盘和鼠标事件,用来控制Linux系统的窗口、鼠标和键盘。

在Ubuntu中可以使用以下命令安装xdotool:

sudo apt-get install xdotool


然后在Python脚本中使用os.system()来执行xdotool命令来切换窗口,例如:

import os
# 切换到第二个终端窗口
os.system('xdotool search --name "Terminal" windowactivate')
# 在第二个终端窗口执行命令
os.system('xdotool search --name "Terminal" key --delay 200 "ssh xxx@111.11.11.1"')


其中search命令可以用来查找窗口的ID,windowactivate命令可以用来激活窗口,key命令可以模拟键盘事件,用来在第二个终端窗口中输入命令。注意,key命令需要设置一定的延迟时间(单位是毫秒),以确保命令能够被正确地输入。

完成命令执行后,再切换回第一个终端窗口,可以使用相同的方法再次调用xdotool命令,例如:

# 切换回第一个终端窗口
os.system('xdotool search --name "Terminal" windowactivate')
# 在第一个终端窗口执行命令
output = os.popen('systemctl status xxx').read()


,os.popen()函数执行的是一个子进程,并不会切换当前的窗口,需要先使用xdotool命令切换到相应的窗口,然后再执行命令。

os.popen()是一个Python内置函数,用于运行命令并返回输出。

要切换窗口,可以使用第三方库pyautogui的函数pyautogui.hotkey()实现。例如,如果您要在Windows上切换到另一个程序,可以按下Alt + Tab键:

import os
import pyautogui

# 运行一些命令
os.popen("notepad.exe")
os.popen("calc.exe")

# 切换到记事本窗口
pyautogui.hotkey('alt', 'tab')

# 切换到计算器窗口
pyautogui.hotkey('alt', 'tab')

这段代码将打开notepad.exe和calc.exe两个程序,然后使用pyautogui.hotkey()函数切换到这些程序的窗口。

请注意,pyautogui和OS库会在不同的操作系统和配置下有不同的行为,可能会出现不兼容的情况。而且,这种方式并不一定是可靠的,因为操作系统和其他应用程序可能会干扰窗口切换的行为。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,根据您的描述,您在使用 os.popen() 函数时遇到了一些问题。该函数在执行 shell 命令时,会默认使用当前窗口作为执行环境。这可能就是为什么您的 Linux 命令在第一个终端窗口中执行的原因。

要解决这个问题,可以使用 subprocess 模块,该模块允许您在创建子进程时对其执行环境进行更精确的控制,包括在指定窗口中执行命令,而不是默认使用当前终端。

以下是一个示例代码,它使用 subprocess 模块在第二个终端窗口中执行命令(假设第二个终端窗口的名称为 "MyTerminal"),并且获得命令输出的内容。

import subprocess

# 在第二个终端窗口中执行命令
command = "echo 'Hello World!'"
process = subprocess.Popen(['gnome-terminal', '--window', '--', 'bash', '-c', f'{command}; echo "\nPress ENTER to exit"; read _'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# 等待命令执行完成并获取输出
stdout, stderr = process.communicate()

# 打印输出
print(f"STDOUT: {stdout.decode()}")
print(f"STDERR: {stderr.decode()}")

在上面的代码中, subprocess.Popen() 函数创建了一个新的终端窗口,并在该窗口中执行了指定的命令。该命令执行后,程序等待用户按下回车键,然后将命令输出作为 stdout 变量返回给程序。

注意,这个代码示例使用 gnome-terminal 作为终端程序,因此您需要确保在您的系统上已经安装了这个程序。如果你使用的是其它终端程序,可以将上面代码中的 gnome-terminal 替换为否定的终端程序即可。

另外,由于您提到说您无法安装 subprocess 模块,您可以尝试以下方法来解决这个问题:

  1. 确保您的 Python 安装包包含 subprocess 模块。通常情况下,Python 的标准库应该已包含该模块,在 Python 2.x 或 Python 3.x 的任何版本中。

  2. 确保你的环境变量设置正确:PATH,PYTHONPATH 等。

如果上述两种方法都不起作用,您可以尝试升级您的 Python 安装包,或者重新安装 Python 包管理器(如 pip)。
如果我的回答解决了您的问题,请采纳!