我正在开发一个多平台Django
项目,该项目打开一个新终端并自动进入 Docker 容器,利用docker exec
.由于该应用程序必须与操作系统无关,因此它可以在 Windows、MacOS 和 Linux 上运行。
这就是我的实现方式:
current_os = platform.system()
exec_command = f"docker exec -it {container_id} /bin/{shell}"
if current_os == "Windows":
command = f"start powershell /c {exec_command}"
elif current_os == "Darwin":
command = f"osascript -e 'tell app \"Terminal\" to do script \"{exec_command}\"'"
elif current_os == "Linux":
command = f"gnome-terminal -- sh -c \"{exec_command}\"" # TODO tests
else:
raise Exception("An unknown OS was detected. Unable to open a terminal.")
if os.system(command) != 0:
raise Exception("There was an error opening a new terminal.")
我的疑问是:gnome-terminal
实际上适用于大多数发行版吗?如果没有,我该如何处理?它的防错性如何?浏览互联网并没有让我找到实际的解决方案。
请记住,我想在打开终端时自动运行命令,并且我需要一个属性来防止终端在运行命令后关闭。
我只能在 Ubuntu 20.04 上测试 Linux 案例。
答案1
正如人们已经指出的那样,不存在“Linux”这样的东西。有“Debian”、“Fedora”、“Arch”、“Gentoo”等及其变体。虽然您可以确定所有这些都会有/bin/sh
,但您不能假设将安装任何特定的终端应用程序。
您可以创建一个常见终端应用程序列表,然后迭代它们,直到找到一个有效的应用程序,例如:
import random
import subprocess
class NoTerminalError(Exception):
pass
possible_terminals = [
('lxterminal', lambda cmd: ['lxterminal', '-e', '/bin/sh', '-c', cmd]),
('xfce4-terminal', lambda cmd: ['xfce4-terminal', '-x', '/bin/sh', '-c', cmd]),
('xterm', lambda cmd: ['xterm', '-e', '/bin/sh', '-c', cmd]),
('gnome-terminal', lambda cmd: ['gnome-terminal', '--', "/bin/sh", "-c", cmd]),
]
def find_terminal():
random.shuffle(possible_terminals)
for name, cmdline in possible_terminals:
try:
subprocess.run(cmdline("/bin/true"), check=True)
return name, cmdline
except subprocess.CalledProcessError:
pass
raise NoTerminalError()
name, cmdline = find_terminal()
print('using terminal', name)
subprocess.run(cmdline('cmatrix'), check=True)
或者您可以在文档中包含“此程序需要在此插入名称”。