OS X & Python 3: Поведение при выполнении команды bash в новом терминале? - PullRequest
0 голосов
/ 24 сентября 2011

Я видел похожие вопросы (например, Выполнение команды в новом окне терминала Mac OS X ), но мне нужно подтвердить эту команду и ее ожидаемое поведение в Mac (которого у меня нет).Если кто-нибудь может запустить в Python 3 Mac следующее:

import subprocess, os
def runcom(bashCommand):
     sp = subprocess.Popen(['osascript'], stdin=subprocess.PIPE, stderr=subprocess.PIPE)
     sp.communicate('''tell application "Terminal"\nactivate\ndo script with command "{0} $EXIT"\nend tell'''.format(bashCommand))

runcom('''echo \\"This is a test\\n\\nThis should come two lines later; press any key\\";read throwaway''')
runcom('''echo \\"This is a test\\"\n\necho \\"This should come one line later; press any key\\";read throwaway''')
runcom('''echo \\"This is testing whether I can have you enter your sudo pw on separate terminal\\";sudo ls;\necho \\"You should see your current directory; press any key\\";read throwaway''')

Во-первых, и в основном, правильна ли команда «порождает новый терминал и выполняет»?(Для справки, эта версия функции runcom взята из этого ответа ниже и намного чище, чем мой оригинал.)

Что касается реальных тестов: первый тест, которыйВнутренние двойные экранированные символы \\n действительно работают.Вторые тесты, которые мы можем поместить (неэкранированные) переводы строк в «скрипт» и по-прежнему работать так же, как точка с запятой.Наконец, последний проверяет, можете ли вы вызывать процесс sudo в отдельном терминале (моя конечная цель).

Во всех случаях новый терминал должен исчезнуть, как только вы «нажмете любую клавишу».Пожалуйста, также подтвердите это.

Если один из них не работает, коррекция / диагностика будет наиболее ценной.Также ценится: есть ли более питонский способ порождения терминала на Mac, чем выполнение на нем (sudo, extended) команд bash?

Спасибо!

Ответы [ 2 ]

1 голос
/ 25 сентября 2011

[...] его ожидаемое поведение [...]

Сложно ответить, поскольку эти команды делают то, что I ожидает от них, а это может не совпадать с тем, что вы ожидают от них.

Что касается реальных тестов: первый тест, который показывает, что внутренние двойные экранированные символы \ n действительно работают.

\\n с двойным обратным слешем действительно работает правильно, так как echo испускает символ новой строки. Однако двойные кавычки не выводятся echo.

Вторые тесты, в которые мы можем помещать (неэкранированные) символы новой строки в «скрипт» и по-прежнему использовать их как точку с запятой.

Это также работает.

Наконец, последний проверяет, можете ли вы вызывать процесс sudo в отдельном терминале (моя конечная цель).

Нет причины, по которой это не должно работать, и действительно так оно и есть.

Во всех случаях новый терминал должен исчезнуть, как только вы «нажмете любую клавишу». Пожалуйста, подтвердите это.

Это не сработает по нескольким причинам:

  • read в bash будет по умолчанию читать всю строку, а не только один символ
  • после выполнения поставляемого вами скрипта нет причин для выхода из оболочки в терминале
  • даже если оболочка будет закрыта, пользователь может настроить Terminal.app так, чтобы он не закрывал окно после выхода из оболочки (это даже настройка по умолчанию)

Другие проблемы:

  • скрипт, который вы вводите для osascript, появится в окне терминала перед его выполнением. в приведенных выше примерах пользователь будет видеть каждое «Это тест [...]» дважды.
  • Я не могу понять, что $EXIT должен делать
  • Команда ls покажет пользователю «текущий каталог» только в том смысле, что текущий рабочий каталог в новом окне терминала всегда будет домашним каталогом пользователя
  • throwaway не будет доступно после того, как скрипт bashCommand выйдет

Наконец, этот скрипт вообще не будет работать в Python 3, потому что он аварийно завершается с TypeError: communicate() принимает в качестве аргумента строку байта, а не строку.

Также ценится: есть ли более питонский способ порождения терминала на Mac [...]

Вы должны заглянуть в PyObjC! Это не обязательно более питонично, но, по крайней мере, вы бы устранили некоторые слои косвенности.

1 голос
/ 24 сентября 2011

У меня нет Python 3, но я немного отредактировал вашу runcom функцию, и она должна работать:

def runcom(bashCommand):
    sp = subprocess.Popen(['osascript'], stdin=subprocess.PIPE, stderr=subprocess.PIPE)
    sp.communicate('''tell application "Terminal"\nactivate\ndo script with command "{0} $EXIT"\nend tell'''.format(bashCommand))
...