2014-01-28 13 views
8

Die docs für Popen erwähnen, dass Sie nicht Ihre ausführbare Pfad relativ zum 'ändern Arbeitsverzeichnis' Kwarg angeben können.subprocess.Popen mit relativen Pfaden

Wenn cwd nicht None ist, wird das Kind das aktuelle Verzeichnis cwd geändert werden, bevor sie ausgeführt wird. Beachten Sie, dass dieses Verzeichnis beim Durchsuchen der ausführbaren Datei nicht berücksichtigt wird. Daher können Sie den Pfad des Programms relativ zu cwd nicht angeben.

Aber Verhalten Python auf meinem System scheint direkt um diese Behauptung zu widersprechen:

[email protected]:/tmp$ mkdir a 
[email protected]:/tmp$ cp /bin/ls /tmp/a/my_ls 
[email protected]:/tmp$ mkdir b 
[email protected]:/tmp$ touch /tmp/b/potato 
[email protected]:/tmp$ cd /home/wim 
[email protected]:~$ python 
Python 2.7.5+ (default, Sep 19 2013, 13:48:49) 
[GCC 4.8.1] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from subprocess import check_output 
>>> check_output(['../a/my_ls'], cwd='/tmp/b') 
'potato\n' 
>>> check_output(['../a/my_ls']) 
OSError: [Errno 2] No such file or directory 

Ist mit relativen Pfaden zu cwd etwas, das abhängig ist Plattform und nicht als verlässlich angesehen werden sollten? Oder ist das ein Dokumentationsfehler?

(diese Frage laicht von einem Kommentar von glglgl here)

Antwort

7

Ja, diese Plattform abhängig ist.

Auf POSIX-Systemen wird der Prozess gegabelt und im untergeordneten Prozess wird eine os.chdir(cwd) ausgeführt, bevor die ausführbare Datei ausgeführt wird.

Unter Windows wird jedoch CreateProcess() API call verwendet und cwd wird als lpCurrentDirectory Parameter übergeben. Es findet keine Verzeichnisänderung statt, und der CreateProcess() Aufruf führt nicht durch, um diesen Parameter zu suchen, wenn nach dem lpApplicationName gesucht wird, um auszuführen.

Um Ihre Anwendung plattformübergreifend zu halten, sollten Sie nicht darauf vertrauen, dass das aktuelle Arbeitsverzeichnis beim Suchen der ausführbaren Datei geändert wird.