在单独的控制台窗口中启动Python脚本......从一个python脚本中启动。

问题描述 投票:0回答:1

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

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

我试过几种方法 subprocess 选项,但最远的结果是启动一个新的窗口,但却......挂掉了。

当然,我希望尽可能地与操作系统无关。我猜测终端仿真器的类型在这里很重要,虽然,除此之外。我应该看看多处理模块吗?

我欢迎任何能帮助我走上正轨的建议,或者指出我观点中任何明显的(或者不那么明显的)缺陷。我想坚持这种情况下的最佳实践,但就是经验不足。谢谢。

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

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管到devnull,但我觉得这样不是很干净。

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

python-3.x subprocess command-line-interface python-multithreading
1个回答
0
投票

到目前为止,我已经让这个在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传给devnull,就可以摆脱乱七八糟的Gnome输出。这个方法让我可以动态调用需要在自己的控制台窗口中运行的模块,脱离主程序。对于运行不需要共享状态的脚本来说,它的工作原理很好,并且能够做到 有点儿 跨平台。

不过,我还是觉得一定有更Pythonic的方法。

注意:我注意到在很多相关的帖子中,"在新窗口中 "的说法会引起一些混淆。这里的 "在新窗口中 "是指应用真的打开了一个新的shell窗口(不幸的是。其中 shell需要硬编码),并将模块作为一个独立的进程启动(主应用程序不会跟踪它)。对于使用这个解决方案的其他人,请记住这一点--如果你需要从主实例中管理IO,这肯定不是一个好办法。

© www.soinside.com 2019 - 2024. All rights reserved.