2010-11-30 22 views
0

Was ist der Unterschied zwischenPython subprocess Popen Parameterdifferenz

subprocess.Popen(['cat','/path/to/file'], stdout=subprocess.PIPE, shell=True) 

und

subprocess.Popen(['cat '+'/path/to/file'], stdout=subprocess.PIPE, shell=True) 

? Ich mache das in Ipython. Für die erste, Ipython einfach hängen. Vielleicht nicht hängen, aber es ist deutlich langsamer. Die zweite ist nur OK.

Weiß einfach nicht warum.

Antwort

4

Die erste läuft eigentlich nur cat (wegen der Art, wie der Befehl geparst wird, wenn Sie shell = True verwenden), und damit hängen, weil es auf Eingabe wartet. Die zweite läuft . Sie können dies sehen, indem Sie:

>>> subprocess.Popen(['ls', '-l']) 
<subprocess.Popen object at 0x10048bdd0> 
>>> total 8 
-rw------- 1 root  wheel 652 Nov 29 09:07 000d94cfc78b4 
srwxr-xr-x 1 nbastin wheel 0 Nov 29 09:06 ics179 
srwxr-xr-x 1 nbastin wheel 0 Nov 29 09:06 icssuis501 
drwx------ 3 nbastin wheel 102 Nov 29 09:06 launch-3ZniHd 
drwx------ 3 nbastin wheel 102 Nov 29 09:06 launch-8QRgz2 
drwx------ 3 nbastin wheel 102 Nov 29 09:06 launch-M5ppWp 
drwx------ 3 nbastin wheel 102 Nov 29 09:06 launchd-137.ztQAmI 
drwx------ 2 nbastin wheel 68 Nov 29 09:57 ssh-LreGlOZPAR 

Versus es mit shell = True tun:

>>> subprocess.Popen(['ls', '-l'], shell = True) 
<subprocess.Popen object at 0x10048bd90> 
>>> 000d94cfc78b4  ics179   icssuis501  launch-3ZniHd  launch-8QRgz2  launch-M5ppWp  launchd-137.ztQAmI ssh-LreGlOZPAR 

Wenn Sie shell = True gesetzt, vorbei an einer Liste als args werden Sie nicht bekommen das Verhalten Sie wollen - Sie müssen eine Zeichenfolge übergeben.

+0

Also meinst du für die erste, die zweite str in der Liste wird einfach ignoriert? – wliao

+0

@wliao: lies das Zeug über 'shell = True'. Es wird die angegebene Zeichenfolge wie in der Shell ausgeführt. also, wenn überhaupt, ist es etwas überraschend, dass es überhaupt funktioniert, wenn man eine Liste bekommt. Es ist nicht empfehlenswert, "shell = True" zu setzen und eine Liste zu geben. –

+0

'shell = True' ist sowohl allgemein böse als auch manchmal die Art, wie du es tun musst. Allerdings gibt es bei Ihrem Befehl keinen Grund, 'shell = True' zu ​​setzen, wenn Sie den vollständigen Pfad zu Ihrer Datei angeben - geben Sie einfach den vollständigen Pfad zu' cat' an. –

0

i getestet, die Proben und fanden heraus, dass der erste, Popen Objekt Rückkehr in ipython gearbeitet, aber die zweite tat das gleiche, aber gedruckt cat: /path/to/file: No such file or directory

i, wenn möglich mit subprocess.Popen mit shell=True vermeiden möchten und eine Liste ['x', '--version'] wie diese verwenden vermeidet die Notwendigkeit Pfadnamen mit sagen `Gräbern in ihnen oder so Dreck

in einem Patch zu zitieren pymp.py i geändert:

p = subprocess.Popen(['mplayer -slave -quiet \'' + target + '\' -include \'' + MPLAYERCONFFILE + '\' 2>/dev/null'], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

zu:

devnull = open('/dev/null', 'w') 
p = subprocess.Popen(['mplayer', '-slave', '-quiet', target, '-include', MPLAYERCONFFILE], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=devnull)