在单独的控制台 window 中启动 Python 脚本...从 python 脚本

Launching a Python script in a separate console window...from a python script

我有一个 python 命令行工具,允许用户 select 各种选项,每个选项一个模块。

其中一个选项是独立的 python 脚本,它不与主程序共享任何 I/O 或状态,但它会持续 运行 并且会被阻塞。我真的很想在一个单独的控制台 window 中启动它,用户将被提示输入,并且它将 运行 直到他们手动退出。

到目前为止,我已经尝试了几个 subprocess 选项,但我得到的最多的是启动一个新的 window,它只是...挂起。

当然,我想尽可能 OS 不可知论者。不过,我猜测终端仿真器的类型在这里很重要。我应该查看多处理模块吗?

我欢迎任何有助于我走上正轨或指出我观点中任何明显(或可能不那么明显)缺陷的建议。我想坚持针对这种情况的最佳实践,但我的经验还不够。谢谢。

编辑:我通过调用实际的子模块使它工作:

os.system("gnome-terminal -e 'bash -c \"python3 -m name.of.module; exec bash\"'")

这工作得很好,但我从启动第二个进程的主程序内部的 Gnome 得到了所有这些丑陋的输出:

# Option “-e” is deprecated and might be removed in a later version of gnome-terminal.
# Use “-- ” to terminate the options and put the command line to execute after it.
# _g_io_module_get_default: Found default implementation local (GLocalVfs) for ‘gio-vfs’
# posix_spawn avoided (fd close requested) 
# _g_io_module_get_default: Found default implementation dconf (DConfSettingsBackend) for ‘gsettings-backend’
# watch_fast: "/org/gnome/terminal/legacy/" (establishing: 0, active: 0)
# unwatch_fast: "/org/gnome/terminal/legacy/" (active: 0, establishing: 1)
# watch_established: "/org/gnome/terminal/legacy/" (establishing: 0)

使用 -- 代替 -e 会导致子进程错误。我还使用 -- 选项测试了其他子进程调用,但我仍然从 Gnome 得到一些难看的输出。我可以通过管道将 stderr 传输到 /dev/null,但我觉得这不是很干净。

这通常是一个明智的解决方案,还是这种糟糕的设计(就我而言)?

到目前为止,我已经在 Linux 和 Mac 上使用了它。不过,它很丑;我会欢迎一个更好的答案,但还没有找到一个。

def open_new_window(module_name):
   if (operating_sys == "linux" or operating_sys == "linux2"):
      os.system(f"gnome-terminal -e 2>/dev/null 'bash -c \"python3 -m app.{module_name}; exec bash\"'")
   if (operating_sys == "darwin"):
      os.system(f"""osascript -e 'tell app "Terminal"
      do script "cd {root_path}; python3 -m app.{module_name}"
      end tell' """)
   else:
      print("[-] Your operating system does not support this utility.\n")

有效。在 linux 选项上将 stdout 传递给 /dev/null 将摆脱混乱的 Gnome 输出。这种方法允许我在自己的控制台 window 中动态调用需要 运行 的模块,与主程序分离。对于不需要共享状态的 运行ning 脚本,它工作得很好并且设法 有点 跨平台。

不过,我觉得必须有更 Pythonic 的方法来做到这一点。

注意:我注意到在许多相关帖子中,"in a new window" 语句引起了一些混淆。 "In a new window" 这里的意思是应用程序从字面上打开了一个新的 shell window (不幸的是, 其中 shell 需要为你硬编码)并将模块作为独立进程启动(主应用程序不会跟踪它)。对于使用此解决方案的其他人,请记住这一点 - 如果您需要从主实例管理 I/O,这当然不是执行此操作的好方法。