Я пытаюсь запустить скрипт оболочки внутри некоторого кода Python, но получаю сообщение об ошибке.
Скрипт Python (test.py):
import os
f = os.popen('/home/test/Downloads/record.sh')
f.close()
Скрипт оболочки (record.sh):
#!/bin/sh
rec -r 16k -c 1 -p | sox -p output.wav silence 1 0.1 1% -1 0.5 1% &
[ 1118] Когда я запускаю:
python test.py
Это сообщение об ошибке, которое я получаю: FAIL sox: `- 'Ошибка записи выходного файла: Сломанный канал
[ 1110] Выполнение одного только сценария оболочки работает нормально (т.е. ./record.sh).
Что я делаю не так? Спасибо.
РЕДАКТИРОВАТЬ НИЖЕ: Я изменил сценарий оболочки, поэтому он выглядит следующим образом (больше нет труб):
#!/bin/sh
rec -r 16k -b 16 -c 1 output.wav silence 1 0.5 0.1% 1 1.0 0.1%
С помощью Стефано у меня есть следующий Python script:
#!/usr/bin/python
from subprocess import Popen, PIPE
output = Popen(["sh", "/home/test/Downloads/data/recorder.sh", ], stdout=PIPE).communicate()[0]
Нужно ли мне все еще использовать PIPE и сообщать биты?
Что мне нужно изменить, чтобы скрипт Python не ждал, пока recordder.sh завершит работу, прежде чем двигаться дальше?
Чтобы запустить скрипт оболочки в python 2.6, используйте модуль commands
:
import commands
status, output = commands.getstatusoutput("./script.sh")
status
теперь является существующим состоянием вашей программы, надеюсь 0
. Вывод такой же, как если бы скрипт выполнялся следующим образом:
{ cmd ; } 2>&1
В python3 метод getstatusoutput перемещен в подпроцесс,
import subprocess
status, output = subprocess.getstatusoutput("./script.sh")
Пожалуйста, обратитесь к
[ 1123]В документации стандартной библиотеки.
Есть больше способов порождения подпроцессов, и вам нужно оценить, какой из них является правильным в вашем случае. Обратитесь к документации для подпроцесса , чтобы прочитать о них.
from subprocess import Popen, PIPE
output = Popen(["sh", "script.sh", ], stdout=PIPE).communicate()[0]
Он будет работать в python 2.6, 2.7, 3.1 и 3.2.
Обратите внимание, что вы не можете использовать сценарий оболочки в этом методе, если вы хотите передать вывод, используйте вместо этого этот метод:
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]
В то время как модуль команд будет принимать «dmesg | grep hda»