[Python-de] probleme mit python 3 popen

Peter Otten __peter__ at web.de
Mo Sep 24 10:49:27 EDT 2018


robert wrote:

> Hoi zäme,
> 
> 
> ich bin dabei scripts von v2 auf v3 zu konvertieren.
> 
> Jetzt habe ich ein Problem mit popen:
> 
> ich konstruiere einen Popen-Aufruf wie folgt:
> 
> 
> Zuerst suche ich wo der virtualenvwrapper installiert ist:
> 
> cmd =['/bin/bash', '-c', 'echo $(which virtualenvwrapper.sh)']
> p =subprocess.Popen(cmd, stdout=PIPE)
> virtualenvwrapper =p.communicate()[0].strip()
> Dann bastle ich einen bash Aufruf, in dem Virtualenvwrapper aktiv ist,
> und nutze diesen um einen Eintrag beim Virtualenwrapper zu löschen.
> Dieses Vorgehen ist nötig, weil sonst bash virtualenvwrapper nicht
> kennt. Hier der Popen-Aufruf:
> commands ="""
> export WORKON_HOME=%(home)s/.virtualenvs\n
> export PROJECT_HOME=/home/robert/Devel\n
> source %(virtualenvwrapper)s\n
> rmvirtualenv %(site_name)s
> """%{
> 'home': os.path.expanduser("~"),
> 'virtualenvwrapper': virtualenvwrapper,
> 'site_name': site_name
> }
> p =subprocess.Popen(
> '/bin/bash', stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
> out, err =p.communicate(commands.encode())
> Das funktionierte mit Python 2.7 gut. Der einzige unterschied war, dass
> ich p.communicate(commands), anstelle von
> p.communicate(commands.encode()) aufrufe. In Python 3 Bekomme ich
> folgende Fehlermeldung: /bin/bash: line 6:
> b/home/robert/.virtualenvs/workbench/bin/virtualenvwrapper.sh: No such
> file or directory es scheint das b vor b/home/robert/.. zu sein, dass
> den Fehler hervorruft. Wie muss ich vorgehen, um dieses Problem zu
> vermeiden? Wenn ich dem Command string zuerst redigiere:
> commands =commands.replace("b'/home", "'/home").encode()
> funktionierts, aber das kann ja keine Lösung sein. Danke Robert

Das Problem ist das Mischen von unicode-strings und byte-strings.

>>> b"BYTES %s" % b"bytes"  # ab 3.5
b'BYTES bytes'
>>> "STR %s" % "str"
'STR str'
>>> "STR %s" % b"bytes"
"STR b'bytes'"

Du kannst also entweder durchgehend Bytes verwenden

cmd = b"..."  # kein Problem solange nur ascii-Zeichen vorkommen

oder durchgehend Strings

p = Popen(..., universal_newlines=True)  # communicate() liefert jetzt str
p = Popen(..., text=True)                # ab 3.7 alternativ



Mehr Informationen über die Mailingliste python-de