Używam eSpeak na Ubuntu i mam skrypt Python 2.7, który drukuje i wypowiada komunikat:
import subprocess
text = 'Hello World.'
print text
subprocess.call(['espeak', text])
eSpeak wydaje pożądane dźwięki, ale zaśmieca powłokę z pewnymi błędami (ALSA lib ..., brak połączenia z gniazdem), więc nie mogę łatwo odczytać tego, co zostało wcześniej wydrukowane. Kod zakończenia to 0.
Niestety nie ma udokumentowanej opcji wyłączenia jej gadatliwości, dlatego szukam sposobu, aby tylko wizualnie ją wyciszyć i utrzymać otwartą powłokę w czystości do dalszej interakcji.
W jaki sposób mogę to zrobić?
python
python-2.7
subprocess
espeak
Rypel
źródło
źródło
os.system
składnię. Ale to tylko dla ilustracji. Trzymaj się podprocesusubprocess.DEVNUL
rozwiązanie.Odpowiedzi:
Przekieruj wyjście do DEVNULL:
W rzeczywistości działa to tak samo, jak uruchomienie tego polecenia powłoki:
źródło
os.devnull
jeślisubprocess.DEVNULL
nie jest dostępny (<3.3), użyjcheck_call()
zamiast,call()
jeśli nie sprawdzasz zwróconego kodu, otwieraj pliki w trybie binarnymstdin/stdout/stderr
, korzystanie zos.system()
powinno być odradzane,&>
nie działash
na Ubuntu i>/dev/null 2>&1
można użyć jawnego .os.devnull
ale przypadkowo go napisałem. Ponadto trzymam się użycia PO,call
ponieważ nie wychwytują potencjalnego wyjątku,check_call
który mógłby wystąpić. W przypadkuos.system
przekierowania była to raczej tylko ilustracja tego, co robi skuteczne wykorzystanie podejścia podprocesowego. Niezupełnie jako druga sugestia.close_fds=True
wsubprocess.call
celu zamknięciaFNULL
deskryptor po podproces istniejeclose_fds=True
, deskryptory plików są zamykane później,fork()
ale wcześniej,execvp()
tzn. są zamykane w procesie potomnym tuż przed uruchomieniem pliku wykonywalnego.close_fds=True
nie będzie działać w systemie Windows, jeśli którykolwiek ze strumieni zostanie przekierowany .close_fds
nie zamyka plików w procesie nadrzędnym .Oto bardziej przenośna wersja (dla zabawy, nie jest to konieczne w twoim przypadku):
źródło
DEVNULL
który nie jest w pełni ogólny, jak ten dostarczony przezsubprocess
; ponieważ jest otwarty,wb
nie można go używaćstdin
.'r+b'
trybu, jeśli go potrzebujesz.Użyj
subprocess.check_output
(nowość w Pythonie 2.7). Pominie stdout i zgłosi wyjątek, jeśli polecenie się nie powiedzie. (W rzeczywistości zwraca zawartość standardowego wyjścia, więc możesz użyć tego później w swoim programie, jeśli chcesz). Przykład:Możesz również stderr stłumić za pomocą:
W przypadku wersji wcześniejszych niż 2.7 użyj
Tutaj możesz stderr za pomocą
źródło
except subprocess.CalledProcessError as e
a następnie użyje.code
lube.output
Począwszy od Python3, nie musisz już otwierać devnull i możesz wywoływać subprocess.DEVNULL .
Twój kod zostanie zaktualizowany jako taki:
źródło
stderr
zstdout
powyższym kodem (lub dołączyć jako kolejny argument), aby ukryć wyjścia. „Wyjścia” są w tytule pytania i co mnie tu doprowadziło… może trywialne, ale pomyślałem, że warto o tym wspomnieć.Dlaczego zamiast tego nie użyć poleceń .getoutput ()?
źródło
text
zawiera cudzysłowy, używa innego kodowania znaków lub jest zbyt duży dla wiersza poleceń c) jest tylko Uniksem (w Pythonie 2)