2014-02-01 3 views
0

Почему это работает:Почему кошка работает и файл открыт?

diff = subprocess.Popen(['cat','foo.txt'], stdout=subprocess.PIPE) 
pr = subprocess.Popen(sublime, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, stdin=diff.stdout) 
pr.wait() 
if pr.returncode == 0: 
    msg = pr.stdout.read() 
    print "message : %s" % msg 
    er = pr.stderr.read() 
    print er 

Но это не делает:

diff = subprocess.Popen('open("foo.txt","r")', stdout=subprocess.PIPE) 

Я пытаюсь запустить возвышенный из командной строки терминала и передать текст, введенный в возвышенной переменной.

Что беспокоит меня, я могу добиться с первого, но он не будет работать на окнах!

+2

Popen специально для открытия исполняемых файлов. Если вы хотите втирать объекты python в подпроцесс, возможно, попробуйте многопроцессорность. – Max

ответ

3

Потому что cat - это командная строка, но open - это функция Python. subprocess с shell=True вызывает что-то вроде bash (и с shell=False, он делает примерно то же, что и bash, но с меньшим количеством парсинга) - так, в основном, он может запускать любую команду, которую вы можете запускать непосредственно в терминале, не открывая другой процесс (как и интерпретатор Python). Вы могли сделать что-то вроде:

subprocess.POpen(r'python -c "open(\"foo.txt\", \"r\")', stdout=subprocess.PIPE) 

но это немного смешно.

Причина, по которой первый код не работает в Windows, заключается в том, что в Windows нет команды cat. Но вы можете делать то, что вы пытаетесь достичь, не вызывая никакого другого подпроцесса, чем возвышенное - по существу, эквивалент sublime < foo.txt, а не cat foo.txt | sublime.

Чтобы сделать это, читать данные из файла в переменную первого, а затем отправить его на подпроцесс с помощью communicate:

sublime = subprocess.POpen(['sublime'], stdout=subprocess.PIPE, stdin=subprocess.PIPE) 
data = open("foo.txt", 'rb').read() 
out, err = sublime.communicate(data) 
+0

, даже если я что-то пишу в возвышенном виде, переменная не содержит ничего в ошибке или ошибке. –

+0

@Ivc: Я попробовал тот же код, который менял текстовый редактор на 'nano', который дал мне эту ошибку' Received SIGHUP или SIGTERM', и когда я trid 'vim', я получил эту ошибку, и оболочка застряла' Vim: Warning: Output is не к терминалу Vim: Предупреждение: вход не с терминала –

+0

@san nano и vim оба считываются из STDIN, только если вы даете им имя файла '-' - то есть do' 'POpen (['nano', ' - '], ...) '. Возможно, что возвышенное делает то же самое. так как это общее соглашение Unix. Кроме того, дважды проверьте, что вы даете те же аргументы возвышенному в этом методе, как и в вашем исходном коде. Но убедить его сбросить свои данные в STDOUT не должно зависеть от того, как генерируется его STDIN. – lvc

Смежные вопросы