Запуск сценария Python в отдельном окне консоли ... из сценария python - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть инструмент командной строки python, который позволяет пользователю выбирать различные параметры, каждый из которых является модулем.

Один из вариантов - это автономный сценарий python, который не разделяет ввод-вывод или состояние с основной программой, но работает постоянно и будет блокироваться. Я бы очень хотел запустить его в отдельном окне консоли, где пользователю будет предложено ввести данные, и он будет работать до тех пор, пока он не выйдет вручную.

До сих пор я пробовал несколько subprocess вариантов, но самое дальнее, что я получил, это запуск нового окна, которое просто ... зависает.

Конечно, я бы хотел быть максимально OS-агности c насколько это возможно. Я предполагаю, что тип эмулятора терминала здесь имеет значение, между прочим. Стоит ли мне смотреть на многопроцессорный модуль?

Я приветствую любые советы, которые помогут мне встать на правильный путь или укажут на любой очевидный (или, возможно, не очень очевидный) fl aws с моей точки зрения. Я хотел бы придерживаться лучших практик для этой ситуации, но я просто недостаточно опытен. Спасибо.

Редактировать: я получил это для работы, вызвав фактический подмодуль:

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, но я не чувствую, что это очень чисто.

Это вообще разумное решение, или это плохой дизайн (с моей стороны)?

1 Ответ

0 голосов
/ 27 апреля 2020

До сих пор я заставил это работать как на Linux, так и на Ма c. Это уродливо, хотя; Я бы приветствовал лучший ответ, но не нашел его.

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")

Это работает. Передача stdout в / dev / null для опции linux избавит от грязного вывода Gnome. Этот метод позволяет мне динамически вызывать модули, которые должны запускаться в собственном окне консоли, отсоединенном от основной программы. Для запуска сценариев, которым не нужно совместно использовать состояние, он работает просто отлично и может быть несколько кроссплатформенным.

Тем не менее, я чувствую, что должно быть больше Pythoni c способ сделать это.

Примечание: я заметил, что на многих связанных постах утверждение "в новом окне" вызывает некоторую путаницу. «В новом окне» здесь означает, что приложение буквально открывает новое окно оболочки (к сожалению, , оболочка должна быть жестко задана для вас) и запускает модуль как отдельный процесс (основное приложение не сохраняет трек это). Для других, использующих это решение, имейте это в виду - это, безусловно, НЕ хороший способ сделать это, если вам нужно управлять вводом / выводом из основного экземпляра.

...