überprüfen ob binary existiert unter Linux

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pycodein
User
Beiträge: 10
Registriert: Dienstag 12. Juni 2007, 15:48

grüß euch.

Ich habe danach gesucht aber nichts passendes leider gefunden.

Ich schreibe gerade ein python script das unter Linux lauft und auf exiv2 einen binary zugreift mittels subprocess.
Das Problem ist das ich nicht davon ausgehen kann das überall exiv2 installiert ist.

Meine Frage darum wie kann ich das am saubersten abfragen, ob ein Programm bzw binary am System vorhanden ist?

Ich denke es wird sicher mehre Möglichkeiten geben. Im Moment mache ich es mit os.path.isfile()

danke!
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

pycodein hat geschrieben:Meine Frage darum wie kann ich das am saubersten abfragen, ob ein Programm bzw binary am System vorhanden ist?
Hallo pycodein!

Willkommen im Python-Forum!

Du könntest auch einfach prüfen ob du einen Fehler bekommst:

Code: Alles auswählen

>>> import subprocess
>>> try:
...     print subprocess.Popen(["hallo"], executable = "hallo")
... except EnvironmentError:
...     print "hallo gibt es nicht"
...     
hallo gibt es nicht
>>>
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
mq
User
Beiträge: 124
Registriert: Samstag 1. Januar 2005, 19:14

gerold hat geschrieben:Du könntest auch einfach prüfen ob du einen Fehler bekommst:

Code: Alles auswählen

>>> import subprocess
>>> try:
...     print subprocess.Popen(["hallo"], executable = "hallo")
... except EnvironmentError:
...     print "hallo gibt es nicht"
...     
hallo gibt es nicht
>>>
Ungeschickte Loesung. Das fuehrt das Programm direkt aus, was nicht immer das ist, was man will.

Das Problem ist, einen Ansatz zu finden, der ohne Ausprobieren auskommt. Ich denke, der beste Weg ist, die Umgebungsvariable PATH auszulesen (geht mit os.environ bzw. os.getenv) und nacheinander zu ueberpruefen, ob in den einzelnen Directories ein File mit dem Namen des Binaries vorhanden ist (os.path.exists). Falls ja, liest du mit os.stat die Infos ueber die Datei aus (das erste Element der zurueckgegebenen Sequenz sind die Permissions) und ueberpruefst, ob es ausfuehrbar ist (die entsprechenden Konstanten befinden sich im Modul stat).
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Der Befehl type gibt eine Fehlermeldung auf stderr aus, wenn er das Programm nicht im PATH findet, ansonsten Informationen auf stdout. Man koennte also schauen, ob ein Aufruf von type etwas auf stderr zurueckliefert oder den returncode anschauen.

Code: Alles auswählen

rbreu@zam285:~> type bla
bash: type: bla: not found
rbreu@zam285:~> echo $?
1
rbreu@zam285:~> type bash
bash is /bin/bash
rbreu@zam285:~> echo $?
0
pycodein
User
Beiträge: 10
Registriert: Dienstag 12. Juni 2007, 15:48

ok danke schonmal!

ich hab mir auch überlegt ans system sowas zuschreiben wie

Code: Alles auswählen

whereis exiv2
und zu schauen was zurückkommt.

$ whereis exiv2
exiv2:

oder

$ whereis exiv2
exiv2: /usr/bin/exiv2 /usr/X11R6/bin/exiv2 /usr/bin/X11/exiv2 /usr/share/man/man1/exiv2.1.gz

aber irgendwie optimal erscheint mir nichts noch davon :)

vielleicht haben ja noch ein paar Ideen dazu, würde mich freuen da ich mich das schon häufiger gefragt habe wie sowas andere lösen.

@Rebecca
schaut sehr gut aus :)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

lumax hat geschrieben:
gerold hat geschrieben:Du könntest auch einfach prüfen ob du einen Fehler bekommst:

Code: Alles auswählen

>>> import subprocess
>>> try:
...     print subprocess.Popen(["hallo"], executable = "hallo")
... except EnvironmentError:
...     print "hallo gibt es nicht"
...     
hallo gibt es nicht
>>>
Ungeschickte Loesung. Das fuehrt das Programm direkt aus, was nicht immer das ist, was man will.
Das Problem ist, einen Ansatz zu finden, der ohne Ausprobieren auskommt.
Hallo lumax!

Das ist jetzt ein Punkt wo man prächtig darüber streiten kann. :P Es ist doch so, dass in 99,99% der Fälle das externe Programm ausgeführt wird und sofort ein Ergebnis zurück liefert. Das habe ich oben mit ``print subprocess.Popen...`` angedeutet. Der Fehler, dass das Programm nicht existiert passiert nur ein oder zwei Mal. So lange, bis sich der Benutzer das Programm "exif2" installiert hat. Dort wo ``print "hallo gibt es nicht"`` steht, könnte man einen Hinweis für den Benutzer ausgeben, dass er "exif2" installieren muss, bevor das Programm läuft.

Und jetzt kommt die Streitfrage: Warum soll ich dann vor jedem Ausführen von "exif2" prüfen ob es installiert ist? Warum verwende ich es nicht einfach und reagiere darauf, falls es beim Ausführen einen Fehler gibt? Das ist in Python nicht nur geduldet, sondern normal.

Ich kenne jetzt "exif2" nicht, aber beim Kommandozeilentool "exif" wird die "Usage"-Information zurück gegeben, wenn "exif" ohne zusätzliche Parameter aufgerufen wird. Man kann also mit dieser Methode auch schon vorher prüfen ob "exif" installiert ist. Das wäre z.B. eine Idee für die Installationsroutine des Programms.

Geschmackssache... :wink:

mfg
Gerold
:-)

PS: OSError scheint besser zum Abfangen des Fehlers geeignet zu sein. Das funktioniert dann unter Windows und Linux.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
lunar

Code: Alles auswählen

from distutils.spawn import find_executable

if find_executable('exiv2'):
     do_something_with_exiv2()
else:
     sys.exit('exiv2 nicht gefunden')
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

lunar hat geschrieben:

Code: Alles auswählen

from distutils.spawn import find_executable
Hi lunar!

Schön! Das gefällt mir. Dann wären wir dort wo so eine Prüfung auch hin gehört. Zur Installation. ;-)
Nur schade, dass "distutils" bei vielen Linux-Distris nicht automatisch mit Python installiert wird. Aber das macht ja nichts, denn man kann ja im Paketverwaltungssystem der Distri "exiv2" als Abhängigkeit angeben.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
lunar

gerold hat geschrieben:
lunar hat geschrieben:

Code: Alles auswählen

from distutils.spawn import find_executable
Schön! Das gefällt mir. Dann wären wir dort wo so eine Prüfung auch hin gehört. Zur Installation. ;-)
Naja, ich verwende distutils auch oft außerhalb von Installationsskripten, da dort doch einige nützliche Klassen und Funktionen enthalten sind. (u.a. auch die Versionklassen StrictVersion und LooseVersion, die sich gut zum Vergleichen von Versionsnummern nutzen lassen).
Ob sowas in die Installation gehört, ist imho auch nicht so sicher. Gerade bei kleinen Skripten ist es doch oft eben ein Vorteil, dass man sie nicht erst langwierig installieren muss, sondern einfach flott ausführen kann. Dann ist eine Überprüfung zur Laufzeit eben doch manchmal sinnvoll ;)
Nur schade, dass "distutils" bei vielen Linux-Distris nicht automatisch mit Python installiert wird.
Tatsache? Welche wären denn das? Ich kenne nur Ubuntu, Debian und Gentoo und alle drei Distributionen installieren den Python-Core immer komplett (oder zumindest mit den distutils).
Benutzeravatar
mq
User
Beiträge: 124
Registriert: Samstag 1. Januar 2005, 19:14

gerold hat geschrieben:
lumax hat geschrieben:
gerold hat geschrieben:Du könntest auch einfach prüfen ob du einen Fehler bekommst:

Code: Alles auswählen

>>> import subprocess
>>> try:
...     print subprocess.Popen(["hallo"], executable = "hallo")
... except EnvironmentError:
...     print "hallo gibt es nicht"
...     
hallo gibt es nicht
>>>
Ungeschickte Loesung. Das fuehrt das Programm direkt aus, was nicht immer das ist, was man will.
Das Problem ist, einen Ansatz zu finden, der ohne Ausprobieren auskommt.
Hallo lumax!

Das ist jetzt ein Punkt wo man prächtig darüber streiten kann. :P Es ist doch so, dass in 99,99% der Fälle das externe Programm ausgeführt wird und sofort ein Ergebnis zurück liefert. Das habe ich oben mit ``print subprocess.Popen...`` angedeutet. Der Fehler, dass das Programm nicht existiert passiert nur ein oder zwei Mal. So lange, bis sich der Benutzer das Programm "exif2" installiert hat. Dort wo ``print "hallo gibt es nicht"`` steht, könnte man einen Hinweis für den Benutzer ausgeben, dass er "exif2" installieren muss, bevor das Programm läuft.

Und jetzt kommt die Streitfrage: Warum soll ich dann vor jedem Ausführen von "exif2" prüfen ob es installiert ist? Warum verwende ich es nicht einfach und reagiere darauf, falls es beim Ausführen einen Fehler gibt? Das ist in Python nicht nur geduldet, sondern normal.
Weiss ich. Ich habe die Frage so verstanden, als wuerde man nach einem Weg suchen, zu pruefen, ob ein Binary vorhanden ist, aber nicht zum Zeitpunkt der Ausfuehrung (sowas koennte man z.B. fuer ein Installations-Script gebrauchen). Deine Loesung ist mehr fuer "Ich will das Programm jetzt ausfuehren und meckern, wenn es nicht da ist", meiner eher "Ich will gucken, ob das Programm existiert". ALso unterschiedliche Loesungen fuer leicht unterschiedliche Probleme :)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

lunar hat geschrieben:
Nur schade, dass "distutils" bei vielen Linux-Distris nicht automatisch mit Python installiert wird.
Tatsache? Welche wären denn das? Ich kenne nur Ubuntu, Debian und Gentoo und alle drei Distributionen installieren den Python-Core immer komplett (oder zumindest mit den distutils).
Hallo lunar!

Ich will dich ja nicht enttäuschen, aber...

Code: Alles auswählen

gps ~ # aptitude show python-dev
Package: python-dev
State: installed
Automatically installed: no
Version: 2.4.3-11ubuntu3
Priority: optional
Section: python
Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
Uncompressed Size: 20,5k
Depends: python (= 2.4.3-11ubuntu3), python2.4-dev (>= 2.4.3-7)
Description: Header files and a static library for Python (default)
 Header files, a static library and development tools for building Python modules, extending the Python interpreter or
 embedding Python in applications.

 Includes the python distutils, which were in a separate package up to version 1.5.2.

 This package is a dependency package, which depends on Debian's default Python version (currently v2.4).

gps ~ #
...ich weiß auch nicht was denen da eingefallen ist.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
lunar

gerold hat geschrieben:
lunar hat geschrieben:
Nur schade, dass "distutils" bei vielen Linux-Distris nicht automatisch mit Python installiert wird.
Tatsache? Welche wären denn das? Ich kenne nur Ubuntu, Debian und Gentoo und alle drei Distributionen installieren den Python-Core immer komplett (oder zumindest mit den distutils).
Hallo lunar!

Ich will dich ja nicht enttäuschen, aber...
:shock: Das ist mir gar nicht aufgefallen...

Mmh, ich habe python-dev iirc nie manuell installiert... trotzdem hatte ich immer die distutils?! Vielleicht kam das schon als Dependency eines anderen Paketes...

Auf jeden Fall ist es ne ziemlich bescheuerte Sache. Dadurch macht man die eigentlich gute Sache - eine feste Standardbibliothek, auf deren Existenz man sich verlassen kann - ja wieder völlig zunichte... :(
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Auf jeden Fall ist es ne ziemlich bescheuerte Sache. Dadurch macht man die eigentlich gute Sache - eine feste Standardbibliothek, auf deren Existenz man sich verlassen kann - ja wieder völlig zunichte... :(
Weiß nicht ob ich mich richtig erinnere (kann es auch nicht nachprüfen, da ich hier im Moment kein Debian verfügbar habe) aber ich meine dass ein Teil der Distutils im Python-Paket ist und nur ein anderer Teil im ``-dev`` Paket. Der Teil, der benötigt wird, um C-Module zu kompilieren. Dummerweise auch der, der benötigt wird, wenn man ``python setup.py install`` ausführt, statt dass nur der Teil für ``build_ext`` ausgelassen wird.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten