То, что вы хотите здесь, это (по-видимому) серия труб:
com[0] | com[1] | ... | com[n-1]
Самый простой способ, если вам не нужно беспокоиться о «плохих» персонажах и оболочках, это просто объединить их всех в одну большую команду оболочки:
p = subprocess.Popen(' | '.join(' '.join(words) for words in com), shell=True, ...)
В качестве альтернативы, так как изначально вы хотите, чтобы stdout = None, вы можете использовать хитрость @ pst, заключающуюся в том, чтобы p изначально был любым объектом с .stdout, равным None. Но вы также должны заметить, что вы зависите от системы, которая закрывает каждый из ваших предыдущих подпроцессов.Popen () (так, чтобы их выходные каналы были близки () d) внутри цикла, что происходит с CPython, но не с Jython ( насколько я понимаю - я на самом деле не использовал Jython). Так что вам может понадобиться более явный цикл:
# assumes len(com) >= 1
p0 = subprocess.Popen(com[0], stdout=subprocess.PIPE)
# don't use stderr=subprocess.PIPE -- if you want stderr to be piped too
# use stderr=subprocess.STDOUT, or create a stderr pipe early manually and
# supply the fd directly; see hints in text below.
for words in com[1:]:
p1 = subprocess.Popen(words, stdin=p0.stdout, stdout=subprocess.PIPE)
# again you don't want to set stderr to subprocess.PIPE here
p0.stdout.close() # now that it's going to p1, we must ditch ours
p0 = p1 # p1 becomes the input to any new p1 we create next time
# at this point, use p0.communicate() to read output
Если вы перенаправите stderr = subprocess.STDOUT в каждом Popen (), это перенаправит вывод ошибок из каждой подкоманды в следующую. Чтобы передать их все в вашу программу, вам сначала нужно создать объект канала на уровне ОС, затем подключить каждый к концу записи этого (одного) канала, а затем пробраться вокруг модуля подпроцесса, чтобы получить «конечный» объект подпроцесса, указывающий на него. , так что его код выбора / опроса будет высасывать любые данные из этого канала. (Поскольку subprocess.communicate () будет считывать только кратные данные из двух таких каналов, вы не можете захватывать выходные данные stderr каждой отдельной подкоманды.)
Примечание: ничего из вышеперечисленного не проверено ...