Как выполнить произвольный скрипт оболочки и передать несколько переменных через Python? - PullRequest
2 голосов
/ 03 апреля 2009

Я создаю плагин приложения на Python, который позволяет пользователям произвольно расширять приложение простыми скриптами (работающими в Mac OS X). Выполнение скриптов Python легко, но некоторым пользователям удобнее работать с такими языками, как Ruby.

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

У кого-нибудь есть предложения, как лучше всего это сделать? Моя цель - предоставить сценариям информацию, которая им необходима, с наименьшим количеством кода, необходимого для доступа к этой информации в сценарии.

Заранее спасибо!

Ответы [ 3 ]

4 голосов
/ 03 апреля 2009

См. http://docs.python.org/library/subprocess.html#using-the-subprocess-module

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

Итак, ваш звонок может выглядеть так

p = subprocess.Popen( args=["script.sh", "-p", p_opt, "-v", v_opt, arg1, arg2] )

Вы поместили произвольные значения Python в аргументы subprocess.Popen.

1 голос
/ 03 апреля 2009

Если вы собираетесь запускать несколько сценариев и вам нужно передать одну и ту же информацию каждому из них, вы можете рассмотреть возможность использования среды (предупреждение, я не знаю Python, поэтому следующий код, скорее всего, отстой):

#!/usr/bin/python 

import os

try:
    #if environment is set
    if os.environ["child"] == "1":
        print os.environ["string"]
except:
    #set environment
    os.environ["child"]  = "1"
    os.environ["string"] = "hello world"

    #run this program 5 times as a child process
    for n in range(1, 5):
        os.system(__file__)
0 голосов
/ 05 апреля 2009

Один из подходов, который вы могли бы использовать, это использовать json в качестве протокола между родительскими и дочерними сценариями, поскольку поддержка json доступна на многих языках и довольно выразительна. Вы также можете использовать канал для отправки произвольного объема данных в дочерний процесс, предполагая, что ваши требования позволяют вам читать дочерние сценарии из стандартного ввода. Например, родитель может сделать что-то вроде (показан Python 2.6):

#!/usr/bin/env python

import json
import subprocess

data_for_child = {
    'text' : 'Twas brillig...',
    'flag1' : False,
    'flag2' : True
}

child = subprocess.Popen(["./childscript"], stdin=subprocess.PIPE)
json.dump(data_for_child, child.stdin)

А вот эскиз детского сценария:

#!/usr/bin/env python
# Imagine this were written in a different language.

import json
import sys

d = json.load(sys.stdin)
print d

В этом тривиальном примере вывод:

$ ./foo12.py
{u'text': u'Twas brillig...', u'flag2': True, u'flag1': False}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...