Выполнить команду терминала из python в новом окне терминала?

Целью здесь является запуск нового файла python в новой оболочке из существующего файла python и существующего файла python в существующей оболочке. Скажем, у меня есть два файла: aaa.py и bbb.py. Позволяет сказать для простоты, что все aaa.py действительно...

subprocess.call('python bbb.py', shell=True)

... и скажем, что bbb.py делает...

print 'It worked'

Теперь цель состоит в том, чтобы запустить aaa.py в терминале 1 и запустить его для запуска bbb.py в терминале 2. Я ожидал бы, что что-то вроде приведенной ниже команды существует, но не может понять это.

subprocess.call_in_new_window('python bb.py', shell=True)

Ответ 1

Нет никакого способа сделать это вообще из оболочки. Что вам нужно сделать, так это запустить программу терминала или какую-нибудь программу запуска, которая сделает это за вас. И способ сделать это отличается для каждой программы терминалов.

В некоторых случаях os.startfile будет делать то, что вы хотите, но это не будет универсальным.

Кроме того, обратите внимание, в общем, вам действительно понадобится абсолютный путь к вашему script, потому что в новом окне терминала будет запущена новая оболочка и, следовательно, не обязательно будет иметь тот же рабочий каталог. Но я проигнорирую это для примеров.


С помощью Windows cmd самый простой способ сделать это - команда start оболочки. Если вы start, то любая программа командной строки, включая python, получит новое окно cmd. Итак, что-то вроде:

subprocess.call('start /wait python bb.py', shell=True)

OS X имеет аналогичную команду, open. И это настоящая программа, а не команда оболочки, поэтому вам не нужно shell=True. Однако запуск командной строки или script с помощью open обычно не открывает новое окно терминала. Фактически, все дело в том, чтобы позволить вам запускать программы, как если бы они были дважды нажаты в Finder, которые никогда не запускают что-либо в терминале, если это не файл .command.

Итак, вы можете создать временный файл оболочки .command и open, который; что-то вроде этого (непроверено):

with tempfile.NamedTemporaryFile(suffix='.command') as f:
    f.write('#!/bin/sh\npython bb.py\n')
    subprocess.call(['open', '-W', f.name])

В качестве альтернативы вы можете явно указать open использовать Terminal.app, что-то вроде этого:

subprocess.call(['open', '-W', '-a', 'Terminal.app', 'python', '--args', 'bb.py'])

Или вы можете script Terminal.app через AppleEvents. Например:

appscript.app('Terminal').do_script('python bb.py')

Событие "do script" открывает новое окно и запускает его аргумент как команду. Если вам нужен более подробный контроль, откройте словарь сценариев в редакторе AppleScript и посмотрите все полезные вещи, которые вы можете сделать.


В Linux или других системах * nix... ну, есть 65102 различных настольных средах, пусковых установках и терминальных программах. Вам нужно работать над всеми из них?

С помощью gnome-терминала просто запуск терминала снова дает вам новое окно, а аргумент -x позволяет указать начальную команду, поэтому:

subprocess.call(['gnome-terminal', '-x', 'python bb.py'])

Многие старые терминалы пытаются быть совместимыми с xterm, что делает то же самое с -e, поэтому:

subprocess.call(['xterm', '-e', 'python bb.py'])
subprocess.call(['rxvt', '-e', 'python bb.py'])

... и т.д.

Откуда вы знаете, какой терминал использует пользователь? Хороший вопрос. Вы можете подойти к родительским процессам самостоятельно, пока не найдете что-то похожее на терминал. Или вы можете просто предположить, что у всех есть xterm. Или вы можете посмотреть, как различные дистрибутивы настраивают терминал по умолчанию и ищут все из них. Или...

Ответ 2

Вы не сможете сделать это, по крайней мере, не так просто, как вы думаете об этом. Я подозреваю, что вы говорите о Mac из-за "терминального окна".

Возможно, вы сможете сделать это с помощью системы X Window, но для этого вам понадобится множество настроек, X-серверов, разрешений и т.д.

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

Windows и оболочки немного не пересекаются.