Ich möchte die gesamte Terminalausgabe unterdrücken, die von einer Funktion erzeugt wird, die ausführbare Dateien ausführt.Wie kann die Terminalausgabe von ausführbaren Dateien, die von Python-Funktionen ausgeführt werden, allgemein stummgeschaltet werden?
Ich habe versucht, die Ausgabe einer Python-Funktion zu unterdrücken, indem Sie einen Kontextmanager verwenden, der stdout und stderr bei jedem Aufruf der Funktion temporär neu definiert. Dies unterdrückt die durch print
Aufrufe in der Funktion erzeugte Terminalausgabe, aber es scheint nicht zu funktionieren, wenn die Funktion ausführbare Dateien aufruft, die Terminalausgabe erzeugen.
Also, wie könnte die Ausgabe von ausführbaren Dateien, die von Python-Funktionen aufgerufen werden, unterdrückt werden?
Mein Code ist unten. Ich habe eine Beispielfunktion eingefügt, die ls
aufruft, um zu versuchen, die Art der Terminalausgabe zu veranschaulichen, die ich unterdrücken möchte (obwohl die Funktion, mit der ich es zu tun habe, anders ist).
#!/usr/bin/env python
import os
import subprocess
import sys
def main():
print("hello")
with silence():
print("there")
print("world")
with silence():
engage_command(command = "ls")
class silence(object):
def __init__(
self,
stdout = None,
stderr = None
):
if stdout == None and stderr == None:
devnull = open(os.devnull, "w")
stdout = devnull
stderr = devnull
self._stdout = stdout or sys.stdout
self._stderr = stderr or sys.stderr
def __enter__(
self
):
self.old_stdout = sys.stdout
self.old_stderr = sys.stderr
self.old_stdout.flush()
self.old_stderr.flush()
sys.stdout = self._stdout
sys.stderr = self._stderr
def __exit__(
self,
exc_type,
exc_value,
traceback
):
self._stdout.flush()
self._stderr.flush()
sys.stdout = self.old_stdout
sys.stderr = self.old_stderr
def engage_command(
command = None
):
process = subprocess.Popen(
[command],
shell = True,
executable = "/bin/bash")
process.wait()
output, errors = process.communicate()
return output
if __name__ == "__main__":
main()
In meinem Fall, ich versuche, die folgende Funktion (statt der ls
Funktion oben) ausgeführt wird:
with propyte.silence():
stream = pyaudio.PyAudio().open(
format = pyaudio.PyAudio().get_format_from_width(1),
channels = 1,
rate = bitrate,
output = True
)
Wenn er gestartet wird, dies erzeugt eine Ausgabe wie folgt aus:
ALSA lib pcm_dsnoop.c:606:(snd_pcm_dsnoop_open) unable to open slave
ALSA lib pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side
ALSA lib pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for 4294967295, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for 4294967295, skipping unlock
Ich möchte diese Ausgabe unterdrücken.
EDIT: Testen a solution von @Matthias bereitgestellt
#!/usr/bin/env python
import contextlib
import os
import subprocess
import sys
def main():
print("hello")
with silence():
print("there")
print("world")
with silence():
engage_command(command = "ls")
@contextlib.contextmanager
def silence():
devnull = os.open(os.devnull, os.O_WRONLY)
old_stderr = os.dup(2)
sys.stderr.flush()
os.dup2(devnull, 2)
os.close(devnull)
try:
yield
finally:
os.dup2(old_stderr, 2)
os.close(old_stderr)
def engage_command(
command = None
):
process = subprocess.Popen(
[command],
shell = True,
executable = "/bin/bash")
process.wait()
output, errors = process.communicate()
return output
if __name__ == "__main__":
main()
Ich habe nicht gelungen, die Terminal-Ausgabe von den print
bei der Unterdrückung oder die ls
und ich bin mir nicht sicher, warum.
Vielen Dank für Ihre ausführliche Lösung. Ich werde das Sounddevice-Modul wie vorgeschlagen untersuchen und werde seine Lösung zum Stummschalten von PortAudio untersuchen. Für den reinen, allgemeinen Ansatz, das Terminal vollständig zum Schweigen zu bringen (sei es für Python-Ausgabe oder ausführbare Dateien, die von Python gestartet wurden), die ich vorgeschlagen habe, war es nicht erfolgreich, die Terminalausgabe zu unterdrücken. Ich habe meinen Code in eine Bearbeitung der Frage eingefügt. Hätten Sie eine Idee, wie Sie es ändern können, damit die Terminalausgabe von 'print' und' ls' unterdrückt wird? – d3pd
Ah, das ist es. Es gab eine Notwendigkeit, mit stdout umzugehen. Nochmals vielen Dank für Ihre klare und detaillierte Lösung. – d3pd