Gibt es in Python eine tragbare und einfache Möglichkeit, um zu testen, ob ein ausführbares Programm vorhanden ist?
Mit einfach meine ich so etwas wie den which
Befehl, der einfach perfekt wäre. Ich möchte PATH nicht manuell durchsuchen oder versuchen, es mit Popen
& al auszuführen und zu sehen, ob es fehlschlägt (das mache ich jetzt, aber stell dir vor, es ist launchmissiles
)
which
das Modul einesAntworten:
Der einfachste Weg, den ich mir vorstellen kann:
Bearbeiten : Das Codebeispiel wurde aktualisiert und enthält nun eine Logik für die Behandlung von Fällen, in denen das angegebene Argument bereits einen vollständigen Pfad zur ausführbaren Datei enthält, dh "which / bin / ls". Dies ahmt das Verhalten des UNIX-Befehls 'which' nach.
Bearbeiten : Aktualisiert, um os.path.isfile () anstelle von os.path.exists () pro Kommentar zu verwenden.
Bearbeiten :
path.strip('"')
scheint hier das Falsche zu sein. Weder Windows noch POSIX scheinen zitierte PATH-Elemente zu fördern.quelle
PATHEXT
env var dacommand
als gültig ist wiecommand.com
wiescript
vsscript.bat
Ich weiß, dass dies eine alte Frage ist, aber Sie können sie verwenden
distutils.spawn.find_executable
. Dies wurde seit Python 2.4 dokumentiert und existiert seit Python 1.6.Auch Python 3.3 bietet jetzt
shutil.which()
.quelle
win32
diedistutils.spawn.find_executable
Implementierung nur nach.exe
der Liste der Erweiterungen, nach denen gesucht wird, anstatt sie zu verwenden%PATHEXT%
. Das ist nicht großartig, aber es könnte für alle Fälle funktionieren, die jemand braucht.from distutils import spawn
php_path = spawn.find_executable("php")
distutils.spawn
nicht zuverlässig verfügbar: Mit meiner Systeminstallation (/ usr / bin / python) von Python 2.7.6 unter OS X 10.10 erhalte ich:,AttributeError: 'module' object has no attribute 'spawn'
obwohl es seltsamerweise auf demselben Computer mit derselben Version von Python funktioniert, aber von eine virtuelle Installation.import distutils.spawn
, oder folgen Sie derfrom distutils import spawn
Syntax und nicht nurimport distutils
. Andernfalls ist es möglicherweise nicht zugänglich und Sie erhalten die oben genanntenAttributeError
Informationen, auch wenn sie vorhanden sind.Python 3.3 bietet jetzt shutil.which () .
quelle
Für Python 3.2 und früher:
Dies ist ein Einzeiler von Jays Antwort , auch hier als Lambda-Funktion:
Oder zuletzt als Funktion eingerückt:
Für Python 3.3 und höher:
Als Einzeiler von Jan-Philip Gehrcke Antwort :
Als def:
quelle
x
wo sie sein solltecmd
os.path.join(path, cmd)
es sich um eine Datei handelt, nein? Schließlich können Verzeichnisse auch das ausführbare Bit gesetzt haben ...mkdir -p -- "$HOME"/bin/dummy && PATH="$PATH":"$HOME"/bin && python -c 'import os; print any(os.access(os.path.join(path, "dummy"), os.X_OK) for path in os.environ["PATH"].split(os.pathsep))' && rmdir -- "$HOME"/bin/dummy
and os.path.isfile(...)
zu den entsprechenden Stellen reicht aus, um das zu behebenDenken Sie daran, die Dateierweiterung unter Windows anzugeben. Andernfalls müssen Sie
is_exe
mithilfe vonPATHEXT
Umgebungsvariablen eine für Windows sehr komplizierte Version schreiben . Möglicherweise möchten Sie nur FindPath verwenden .OTOH, warum machst du dir überhaupt die Mühe, nach der ausführbaren Datei zu suchen? Das Betriebssystem erledigt dies für Sie im Rahmen des
popen
Aufrufs und löst eine Ausnahme aus, wenn die ausführbare Datei nicht gefunden wird. Sie müssen lediglich die richtige Ausnahme für das jeweilige Betriebssystem abfangen. Beachten Sie, dass unter Windows imsubprocess.Popen(exe, shell=True)
Hintergrund ein Fehler auftritt, wenn erexe
nicht gefunden wird.Einbeziehung
PATHEXT
in die obige Implementierung vonwhich
(in Jays Antwort):quelle
yield
inext_candidates
gab mir ein besseres Verständnis dafür, wie dieses Schlüsselwort funktioniertFür * nix-Plattformen (Linux und OS X)
Das scheint für mich zu funktionieren:
Herausgegeben auf die Arbeit an Linux, dank Mestreion
Wir verwenden hier den eingebauten Befehl
type
und überprüfen den Exit-Code. Wenn es keinen solchen Befehl gibt,type
wird er mit 1 (oder einem Statuscode ungleich Null) beendet.Das Bit über stdout und stderr besteht nur darin, die Ausgabe des
type
Befehls stumm zu schalten , da wir nur am Exit-Statuscode interessiert sind.Anwendungsbeispiel:
quelle
type
ist eine eingebaute Shell, keine ausführbare Datei, alsosubprocess.call()
schlägt hier fehl.OSError: [Errno 2] No such file or directory
. Vielleicht ist in Mactype
ein tatsächlicher Befehlshell=True
und ersetzen["type", cmd]
für"type " + cmd
Im os.path- Modul finden Sie einige nützliche Funktionen für Pfadnamen. Um zu überprüfen, ob eine vorhandene Datei ausführbar ist, verwenden Sie os.access (Pfad, Modus) im Modus os.X_OK.
BEARBEITEN: Bei den vorgeschlagenen
which()
Implementierungen fehlt ein Hinweis -os.path.join()
zum Erstellen vollständiger Dateinamen.quelle
Da es einfacher ist, um Vergebung als um Erlaubnis zu bitten, würde ich einfach versuchen, sie zu verwenden und den Fehler abzufangen (OSError in diesem Fall - Ich habe überprüft, ob eine Datei nicht vorhanden ist und die Datei nicht ausführbar ist und beide OSError geben).
Es hilft, wenn die ausführbare Datei so etwas wie ein
--version
Flag hat, das ein schnelles No-Op ist.Dies ist keine allgemeine Lösung, aber der einfachste Weg für viele Anwendungsfälle - solche, bei denen der Code nach einer einzigen bekannten ausführbaren Datei suchen muss.
quelle
--version
ein Programm namens aufzurufenlaunchmissiles
!launchmissies
es sei denn, Sie möchten Raketen abschießen? Besser, es auszuführen und auf Exit-Status / Ausnahmen zugit
die Sie wahrscheinlich nicht blind ausführen möchten.Ich weiß, dass ich hier ein bisschen ein Nekromant bin, aber ich bin über diese Frage gestolpert und die akzeptierte Lösung hat nicht in allen Fällen für mich funktioniert. Ich dachte, es könnte nützlich sein, sie trotzdem einzureichen. Insbesondere die Erkennung des "ausführbaren" Modus und die Anforderung, die Dateierweiterung bereitzustellen. Darüber hinaus funktionieren sowohl Python3.3
shutil.which
(verwendetPATHEXT
) als auch Python2.4 +distutils.spawn.find_executable
(versucht nur das Hinzufügen'.exe'
) nur in einer Teilmenge von Fällen.Also schrieb ich eine "Super" -Version (basierend auf der akzeptierten Antwort und dem
PATHEXT
Vorschlag von Suraj). Diese Version vonwhich
erledigt die Aufgabe etwas gründlicher und probiert zuerst eine Reihe von "Breitphasen" -Breiten-First-Techniken aus und versucht schließlich feinkörnigere Suchen über denPATH
Raum:Die Verwendung sieht folgendermaßen aus:
Die akzeptierte Lösung nicht für mich Arbeit in diesem Fall, da es gab Dateien wie
meld.1
,meld.ico
,meld.doap
usw. auch in dem Verzeichnis, von denen stattdessen zurückgegeben wurden (vermutlich lexikographisch ersten seit) , weil der ausführbare Test in der akzeptierten Antwort war unvollständig und geben Fehlalarm.quelle
Das beste Beispiel sollte das Python-Bulit-In-Modul shutil.which () in Python 3 sein. Der Link lautet https://hg.python.org/cpython/file/default/Lib/shutil.py
quelle
Ich habe in StackOverflow etwas gefunden, das das Problem für mich gelöst hat. Dies funktioniert, vorausgesetzt, die ausführbare Datei verfügt über eine Option (wie --help oder --version), die etwas ausgibt und einen Exit-Status von Null zurückgibt. Siehe Ausgabe in Python-Aufrufen an ausführbare Dateien unterdrücken - das "Ergebnis" am Ende des Codeausschnitts in dieser Antwort ist Null, wenn sich die ausführbare Datei im Pfad befindet, andernfalls ist es höchstwahrscheinlich 1.
quelle
Dies scheint einfach zu sein und funktioniert sowohl in Python 2 als auch in Python 3
quelle
command -v executable
odertype executable
universell sein. Es gibt Fälle, in denen auf Macs die erwarteten Ergebnisse nicht zurückgegeben werden.Eine wichtige Frage lautet: " Warum müssen Sie testen, ob eine ausführbare Datei vorhanden ist?" Vielleicht nicht? ;-);
Vor kurzem brauchte ich diese Funktionalität, um den Viewer für PNG-Dateien zu starten. Ich wollte einige vordefinierte Viewer durchlaufen und den ersten ausführen, der existiert. Zum Glück bin ich rübergekommen
os.startfile
. Es ist viel besser! Einfach, portabel und verwendet den Standard- Viewer auf dem System:Update: Ich habe mich geirrt
os.startfile
, portabel zu sein ... Es ist nur Windows. Auf dem Mac müssen Sie denopen
Befehl ausführen . Undxdg_open
unter Unix. Es gibt ein Python-Problem beim Hinzufügen von Mac- und Unix-Unterstützung füros.startfile
.quelle
Sie können die externe Bibliothek "sh" ( http://amoffat.github.io/sh/ ) ausprobieren .
quelle
Windows-Unterstützung hinzugefügt
quelle
Sie können feststellen, ob eine Datei mit dem OS-Modul vorhanden ist. Insbesondere eine ausführbare Datei scheint ziemlich unportabel zu sein, wenn man bedenkt, dass viele Dinge unter nix ausführbar sind, die nicht unter Windows sind, und umgekehrt.
quelle
Es scheint, dass die offensichtliche Wahl "welche" ist, die die Ergebnisse über popen analysiert, aber Sie könnten es auch anders mit der os-Klasse simulieren. In Pseudopython würde es so aussehen:
quelle
which
Befehl. Es gibt eine UnxUtils-Version, aber Sie müssen die Erweiterung kennen / angeben, sonst wird das Programm nicht gefunden.Grundsätzlich möchten Sie also eine Datei im bereitgestellten Dateisystem finden (nicht unbedingt nur in PATH-Verzeichnissen) und prüfen, ob sie ausführbar ist. Dies führt zu folgendem Plan:
Ich würde sagen, dies auf tragbare Weise zu tun, erfordert viel Rechenleistung und Zeit. Ist es wirklich das, was du brauchst?
quelle
In einer Standard-Python-Distribution (z . B. unter Windows ) gibt es ein which.py- Skript
'\PythonXX\Tools\Scripts\which.py'
.BEARBEITEN:
which.py
hängtls
davon ab, dass es nicht plattformübergreifend ist.quelle
Keines der vorherigen Beispiele funktioniert auf allen Plattformen. Normalerweise funktionieren sie unter Windows nicht, da Sie ohne die Dateierweiterung ausführen und eine neue Erweiterung registrieren können. Wenn beispielsweise Python unter Windows gut installiert ist, reicht es aus, 'file.py' auszuführen, und es funktioniert.
Die einzige gültige und tragbare Lösung bestand darin, den Befehl auszuführen und den Fehlercode anzuzeigen. Jede anständige ausführbare Datei sollte eine Reihe von aufrufenden Parametern haben, die nichts bewirken.
quelle
Verwenden der Python-Fabric-Bibliothek:
quelle
which(1)
welches nicht auf allen Systemen vorhanden ist.