В коде Python, который вы разместили, вы не используете правильные потоки:
inputready, outputready, exceptready = select.select(
[proc.stdout, proc.stderr], # read list
[proc.stdout, proc.stderr], # write list
[proc.stdout, proc.stderr], # error list.
0) # time out.
Я не пытался это исправить, но держу пари, что чтение и запись в один и тот же набор потоков неверны.
В вашей выборке несколько ошибок.Во-первых, исполняемый файл python, который вы запускаете как дочерний процесс, не выдает никаких результатов.Во-вторых, существует условие гонки, поскольку вы можете вызывать select()
5 раз подряд, прежде чем дочерний процесс выдаст выходные данные, и в этом случае вы убьете процесс перед чтением чего-либо.
Я исправил трипроблемы, упомянутые выше (список записи, запуск процесса, который производит вывод и состояние гонки).Попробуйте этот пример и посмотрите, работает ли он для вас:
#!/usr/bin/python
import subprocess, os, select, time
path = "/usr/bin/python"
proc = subprocess.Popen([path, "foo.py"], shell=False,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
for i in xrange(0,5):
time.sleep(1)
inputready, outputready, exceptready = select.select(
[proc.stdout, proc.stderr], [proc.stdin,],
[proc.stdout, proc.stderr, proc.stdin], 0)
if not inputready:
print "No Data",
print inputready, outputready, exceptready
for s in inputready:
print s.fileno(),s.readline()
proc.terminate()
print "After Terminating"
for i in xrange(0,5):
inputready, outputready, exceptready = select.select(
[proc.stdout, proc.stderr], [proc.stdin,],
[proc.stdout, proc.stderr, proc.stdin], 0)
if not inputready:
print "No Data",
print inputready, outputready, exceptready
for s in inputready:
print s.fileno(),s.readline()
Файл foo.py
, который я использовал, содержал это:
#!/usr/bin/python
print "Hello, world!"
Следующая версия (в основном удалена излишняя)вывод для облегчения чтения результатов):
#!/usr/bin/python
import subprocess, os, select, time
path = "/usr/bin/python"
proc = subprocess.Popen([path, "foo.py"], shell=False,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
for i in xrange(0,5):
time.sleep(1)
inputready, outputready, exceptready = select.select(
[proc.stdout, proc.stderr], [proc.stdin,],
[proc.stdout, proc.stderr, proc.stdin], 0)
for s in inputready:
line = s.readline()
if line:
print s.fileno(), line
proc.terminate()
print "After Terminating"
for i in xrange(0,5):
time.sleep(1)
inputready, outputready, exceptready = select.select(
[proc.stdout, proc.stderr], [proc.stdin,],
[proc.stdout, proc.stderr, proc.stdin], 0)
for s in inputready:
line = s.readline()
if line:
print s.fileno(), line
Дает следующий вывод:
5 Привет, мир!
После завершения
Обратите внимание, что по какой-то причине использование параметра timeout
в select.select()
не дало ожидаемых результатов в моей системе, и я вместо этого прибегнул к использованию time.sleep()
.
Только к вашему сведению, запуск python как
/usr/bin/python 2>&1|tee test.out
, кажется, работает нормально.
Вы не можете получить этот эффект, потому что этот пример все еще дает интерпретатору python управляющий tty.Без управляющего tty интерпретатор python не печатает версию Python и не отображает приглашение >>>
.
Примером закрытия может быть что-то вроде следующего.Вы можете заменить /dev/null
файлом, содержащим команды для отправки интерпретатору.
/usr/bin/python </dev/null 2>&1|tee test.out
Если вы перенаправляете что-либо , кроме управляющего tty (клавиатура), в качестве стандартного ввода дляпроцесс, вы не получите вывод от интерпретатора Python.Вот почему ваш код не работает.