2010-11-12 5 views
2

J'ai un script simple que j'utilise pour automatiser les appels CLI à notre logiciel (Moab Workload Manager) en test, pour éviter d'avoir à utiliser l'indicateur '--xml' pour obtenir la sortie xml et puis passez-le à travers bien rangé afin qu'il soit facilement lisible. Il utilise un appel subprocess.Popen pour exécuter la commande, puis utilise str.strip() et str.replace() pour effectuer un nettoyage mineur sur le fichier XML renvoyé afin de faciliter l'inspection visuelle. Le code en question est ici:Python 3 erreur de sortie sous-processus.PIPE


cmdString = "%s --xml" % cmd 
cmdList = cmdString.split() 

cmdRun = subprocess.Popen(cmdList, 
    stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE) 

crOut,crErr = cmdRun.communicate() 

xmlOutput = crOut.strip().replace("><",">\n<").replace("\" ","\"\n") 


Quand je lance ce (j'ai récemment amélioré mon Python à Python 3.1.2) Je reçois maintenant l'erreur suivante:


Traceback (most recent call last): 
    File "/usr/local/bin/xmlcmd", line 50, in <module> 
    runXMLCmd(getCmd()) 
    File "/usr/local/bin/xmlcmd", line 45, in runXMLCmd 
    xmlOutput = crOut.strip().replace("><",">\n<") 
TypeError: expected an object with the buffer interface 


Il semble que l'appel de communiquent() renvoie des tableaux d'octets, mais dans l'interpréteur python, si je le fais, je peux le faire avec dir(bytes). toujours voir les fonctions strip() et replace(). Quelqu'un sait-il comment faire ça?

Merci.

Répondre

3

bytes.replace() octets comme arguments attend:

crOut.strip().replace(b"><", b">\n<").replace(b"\" ", b"\"\n") 

Bien qu'en général, il pourrait être préférable de décoder l'entrée au texte unicode le plus tôt possible. Et les transformations à effectuer sur le texte (pas d'octets).

1

Vous devez utiliser crOut.decode("utf-8") et effectuer le .replace dans la chaîne renvoyée.

1

En python 3.2, l'utilisation de decode ('ascii') a corrigé des erreurs de type unicode et de type difficiles à tracer. Indépendamment de l'octet ou bytearray le décodage se convertira en chaîne comme souhaité.

pipe = subprocess.Popen("cmd", 1024, stdout=subprocess.PIPE) 
while pipe.returncode == None: 
    lines = pipe.communicate()[0] 
    lines = lines.decode('ascii') 
    for line in lines.splitlines(): 
     if (re.search('^---', line)): 
      pass # do stuff 

A partir du manuel,

bytes.decode(encoding="utf-8", errors="strict") 
bytearray.decode(encoding="utf-8", errors="strict") 
Return a string decoded from the given bytes. 
Default encoding is 'utf-8'. errors may be given to set a 
different error handling scheme.