Передать вывод команды в интерактивную сессию Python? - PullRequest
2 голосов
/ 23 февраля 2010

То, что я хотел бы сделать, это что-то вроде

 $echo $PATH | python --remain-interactive "x = raw_input().split(':')"
 >>>
 >>> print x
 ['/usr/local/bin', '/usr/bin', '/bin']

Полагаю, решение ipython будет лучшим. Если это недостижимо, каким было бы ваше решение для ситуации, когда я хочу обрабатывать вывод различных других команд? Я использовал подпроцесс раньше, чтобы сделать это, когда был в отчаянии, но он не идеален.

ОБНОВЛЕНИЕ: Так что это приближается к конечному результату:

 echo $PATH > /tmp/stdout.txt; ipython -i -c 'stdout = open("/tmp/stdout.txt").read()'

Теперь, как мы можем согнуть это в форму

 echo $PATH | pyout

, где pyout - «волшебное решение всех моих проблем». Это может быть сценарий оболочки, который записывает вывод по конвейеру, а затем запускает ipython. Все, что сделано, терпит неудачу по тем же причинам, по словам БП.

Ответы [ 3 ]

2 голосов
/ 23 февраля 2010

В IPython вы можете сделать это

x = !echo $$$$PATH

Двойной побег $ - это боль, хотя

Вы могли бы сделать это, я думаю

PATH="$PATH"
x = !echo $PATH
x[0].split(":")
1 голос
/ 23 февраля 2010

Переключатель --remain-interactive, который вы ищете, это -i. Вы также можете использовать переключатель -c, чтобы указать команду для выполнения, например __import__("sys").stdin.read().split(":"). Итак, что вы попробуете: (не забывайте об экранировании строк!)

echo $PATH | python -i -c x = __import__(\"sys\").stdin.read().split(\":\")

Однако это все, что будет отображаться:

>>>

Так почему же это не работает? Потому что ты обжигаешь. Интерпретатор python пытается интерактивно читать команды из того же sys.stdin, из которого вы читаете аргументы. Поскольку echo завершается, sys.stdin закрывается и дальнейший ввод невозможен.

По той же причине, что-то вроде:

echo $PATH > spam
python -i -c x = __import__(\"sys\").stdin.read().split(\":\") < spam

... потерпит неудачу.

Что бы я сделал:

echo $PATH > spam.bar
python -i my_app.py spam.bar

В конце концов, open("spam.bar") является файловым объектом, как sys.stdin: :)

0 голосов
/ 23 февраля 2010

Из-за аксиомы Питона «Должен быть один - и, желательно, только один - очевидный способ сделать это». Я уверен, что не будет лучшего способа взаимодействия с другими процессами, чем 1002 * модуль .

Может помочь, если вы скажете, почему что-то вроде следующего "не идеально":

>>> process = subprocess.Popen(['cmd', '/c', 'echo %PATH%'], stdout=subprocess.PIPE)
>>> print process.communicate()[0].split(';')

(В вашем конкретном примере вы могли бы использовать os.environ, но я понимаю, что это не совсем то, что вы спрашиваете.)

...