【问题标题】:Launching a Python script in a separate console window...from a python script在单独的控制台窗口中启动 Python 脚本...从 python 脚本
【发布时间】:2020-08-10 12:10:48
【问题描述】:

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

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

到目前为止,我已经尝试了几个 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 传输到 /dev/null,但我觉得这不是很干净。

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

【问题讨论】:

  • 我会尝试subprocessPopen 或类似)选项shell=True

标签: python-3.x subprocess command-line-interface python-multithreading


【解决方案1】:

到目前为止,我已经让它在 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 输出。这种方法允许我动态调用需要在自己的控制台窗口中运行的模块,与主程序分离。对于不需要共享状态的运行脚本,它工作得很好,并且设法有点跨平台。

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

注意:我在许多相关帖子中注意到,“在新窗口中”的说法会引起一些混乱。这里的“在新窗口中”意味着应用程序实际上会打开一个新的 shell 窗口(不幸的是,which shell 需要为您硬编码)并将模块作为独立进程启动(主应用程序不会跟踪它)。对于使用此解决方案的其他人,请记住这一点 - 如果您需要从主实例管理 I/O,这肯定不是一个好方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 1970-01-01
    • 2013-02-08
    • 2019-03-16
    相关资源
    最近更新 更多