Синтаксис выполнения переносимых команд реализован в Python - PullRequest
1 голос
/ 08 августа 2009

Python не очень хороший язык в , определяющем набор команд для запуска. Баш есть. Но Bash не работает наивно на Windows.

Предыстория: я пытаюсь создать набор программ - с установленными отношениями зависимости между ними - на mac / win / linux. Что-то вроде macports, но должно работать на всех трех перечисленных платформах.

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

post-destroot {
    xinstall -d ${destroot}${prefix}/share/emacs/${version}/leim
    delete ${destroot}${prefix}/bin/ctags
    delete ${destroot}${prefix}/share/man/man1/ctags.1
    if {[variant_isset carbon]} {
        global version
        delete ${destroot}${prefix}/bin/emacs ${destroot}${prefix}/bin/emacs-${version}
    }
}

Вышеприведенный фрагмент взят из Emacs Portfile в macports . Обратите внимание на использование переменных, условных выражений, функций ... помимо указания простого списка команд для выполнения в этом порядке.

Хотя синтаксис не Python, фактическая семантика выполнения должна быть отложена до Python с использованием подпроцесса или чего-либо еще. Короче говоря, я должен быть в состоянии «запустить» такой скрипт ... но для каждой команды вызывается указанная функция ловушки, которая фактически выполняет любую команду, переданную в качестве аргумента. Я надеюсь, вы поняли идею.

Ответы [ 3 ]

2 голосов
/ 08 августа 2009

Звучит так, будто вам нужна комбинация PyParsing и Подпроцесс Python .

Мне кажется, что подпроцесс немного сбивает с толку, несмотря на MOTW , так что я часто использую этот вид кода-обертки.

from subprocess import Popen, PIPE

def shell(args, input=None):
    p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate(input=input)
    return stdout, stderr
1 голос
/ 08 августа 2009

Нед Батчелдер, в этом посте , перечислены несколько десятков различных инструментов, которые вы можете выбрать для анализа в Python любого произвольного языка (хотя я не совсем понимаю, почему вы не хотите использовать сам Python как «язык для определения набора команд для выполнения», я уверен, у вас есть свои причины). Как упоминает Грегг, одним из этих инструментов Ned списков является pyparsing, но есть и более тридцати других, поэтому вы можете посмотреть, прежде чем выбрать тот, который вам по вкусу.

Как только вы преобразовали свой исходный язык ввода в синтаксическое дерево или другое удобное представление в памяти, вы можете просто пройтись по дереву и выполнять его по ходу (вставка значений переменных, переходы по условным выражениям и циклам и т. Д.). Помимо способности запускать внешние процессы (например, через подпроцесс, независимо от того, завернуты ли они, как подсказывает Грегг, или нет), не забывайте, что сам Python может выполнять некоторые ваши элементарные команды, не нарушая пот, и, когда это возможно, это будет значительно быстрее, чем делегирование выполнения дочернему процессу (действительно, одной из первых причин успеха Perl было то, что он мог делать много вещей в одном процессе, в то время как sh отбрасывался как сумасшедший; современные потомки sh как bash и ksh взял урок и теперь внедрил множество встроенных модулей, которые могут выполняться в том же процессе, что и основной скрипт; -).

Например, эта команда delete в вашем примере может быть реализована "внутренне" через os.unlink (сейчас не может ссылаться на онлайн-документы Python, поскольку python.org в настоящее время недоступен из-за проблем с HW ;-) .

0 голосов
/ 10 августа 2009

Вот мое тривиальное предложение: проанализируйте его с помощью регулярного выражения в Python, чтобы оно стало

def post_destroot():
    xinstall ('-d', '${destroot}${prefix}/share/emacs/${version}/leim')
    delete ('${destroot}${prefix}/bin/ctags')
    delete ('${destroot}${prefix}/share/man/man1/ctags.1')
    if test('variant_isset', 'carbon'):
        global('version')
        delete('${destroot}${prefix}/bin/emacs', '${destroot}${prefix}/bin/emacs-${version}')

Я думаю, нетрудно написать функции xinstall(), delete() и test(), тем более что в Python уже есть встроенная функция для форматирования строк "{destroot}".format(dictionary).

Но зачем? Попробуйте заглянуть в модуль distutils из стандартной библиотеки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...