2017-08-25 6 views
1

En Python J'utiliseRetirez la sortie de tous les sous-processus en Python sans accès au code

sys.stdout = None 

avant quelques appels que je ne contrôle pas. Ces appels peuvent appeler certains sous-processus qui écrivent sur stdout.

Comment puis-je éviter ces appels de sous-processus pour écrire dans stdout?

Encore une fois, je n'ai pas la propriété du code qui appelle le sous-processus. Il semble subprocess.Popen (et similaire) n'honore pas sys.stdout.

+0

https://stackoverflow.com/questions/2828953/silence-the-stdout-of-a-function-in-python-without-trashing-sys-stdout-and-resto Est-ce que cela fait l'affaire? – Uvar

Répondre

0

Oui, la redirection sys.stdout ne fonctionne que pour les impressions python. Lorsqu'un sous-processus est appelé via subprocess, python ne capture pas la sortie par défaut et laisse le processus s'exécuter normalement. Il n'y a aucun moyen de supprimer facilement la sortie du processus.

Je suppose que vous pouvez créer un fichier subprocess.py au même niveau que le code python vous ne pouvez pas changer (ou avant le subprocess.py officiel) pour changer Popen contenu, mais cela voudrait dire importer le module officiel de votre module de stub, python hardcoding chemin, ... faisable, mais il y a une approche plus simple.

Voici un hack pour python 3 que je l'ai testé et qui fonctionne:

  • recherchez le fichier subprocess.py dans l'installation de python et le copier de côté le module que vous ne pouvez pas changer (sur ma machine C:\python34\lib\subprocess.py)
  • ajouter une seule ligne dans ce fichier

le code (autour de la ligne 750):

def __init__(self, args, bufsize=-1, executable=None, 
      stdin=None, stdout=None, stderr=None, 
      preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS, 
      shell=False, cwd=None, env=None, universal_newlines=False, 
      startupinfo=None, creationflags=0, 
      restore_signals=True, start_new_session=False, 
      pass_fds=()): 
    """Create new Popen instance.""" 

    _cleanup() 

ajouter maintenant (avant _cleanup()):

stderr = stdout = DEVNULL 

qui force la sortie standard et erreur null appareil: pas de sortie

maintenant les inconvénients:

    dépendant
  • de la version python installée. Peut fonctionner avec d'autres versions mais il n'est pas recommandé de mélanger les paquets.
  • copie l'ensemble de fichiers subprocess.py au lieu de patcher les appels nécessaires juste

En dehors de cela, il est un travail de 5 minutes et cela fonctionne. Je vous recommande de garder cela comme une solution temporaire et de faire quelque chose à propos de ce "code qui ne peut pas être changé" à un moment donné.

0

Vous pouvez remplacer subprocess.Popen avec une fonction personnalisée qui supprime stdout et stderr:

import subprocess 
import inspect 

def Popen(*args, **kwargs): 
    sig = inspect.signature(real_popen) 
    bound_args = sig.bind(*args, **kwargs).arguments 
    bound_args['stdout'] = subprocess.DEVNULL 
    bound_args['stderr'] = subprocess.DEVNULL 
    return real_popen(**bound_args) 

real_popen = subprocess.Popen 
subprocess.Popen = Popen 

caveat:

Si vous avez du code qui tente de lire la sortie du processus, il échouera.