Test ob ein Programm installiert ist

Anfängerfragen zum Programmieren mit PureBasic.
Sommertv
Beiträge: 68
Registriert: 26.04.2019 10:31
Computerausstattung: Lenovo W500, Debian Stable, Purebasic 5.70 (momentan die Testversion)
Wohnort: Mühldorf am Inn

Test ob ein Programm installiert ist

Beitrag von Sommertv »

Hallo,
wie kann ich feststellen, ob ein Programm oder eine lib installiert ist?
Auf der Shell würd ich's so machen:
$1 = "openssl"
if [[ -f $(which $1 2>/dev/null) ]]
then
echo "$1 vorhanden"
else
echo "bitte $1 installieren!"
fi

Danke im Vorab
Kurt
Wenn einem die einfachen Dinge net einfallen, klappt's meistens umständlich...
Benutzeravatar
Programie
Beiträge: 1280
Registriert: 06.08.2005 22:56
Computerausstattung: https://www.sysprofile.de/id160800
Wohnort: Gernsbach
Kontaktdaten:

Re: Test ob ein Programm installiert ist

Beitrag von Programie »

Der einfachste Weg ist hier die Verwendung von RunProgram() mit deinem "which" Aufruf in Verbindung mit ProgramExitCode():

Code: Alles auswählen

EnableExplicit

Procedure ProgramExists(program$)
  Protected program = RunProgram("which", program$, "", #PB_Program_Open | #PB_Program_Wait)
  If IsProgram(program)
    If ProgramExitCode(program) = 0
      ProcedureReturn #True
    EndIf
  EndIf
  
  ProcedureReturn #False
EndProcedure

If ProgramExists("openssl")
  Debug "Program existiert"
Else
  Debug "Programm existiert nicht"
EndIf
BildBildBildBild
Sommertv
Beiträge: 68
Registriert: 26.04.2019 10:31
Computerausstattung: Lenovo W500, Debian Stable, Purebasic 5.70 (momentan die Testversion)
Wohnort: Mühldorf am Inn

Re: Test ob ein Programm installiert ist

Beitrag von Sommertv »

Guten Morgen,
danke... das war ein guter Denkanstoss...
Ich bekomm bei deiner Variante immer False zurück, egal wie ich wende oder drehe, aber k.A. warum's nicht funktioniert, eigentlich sollte which bei Erfolg 0 zurück geben, sonst 1
Aber so klappt's:

Code: Alles auswählen

EnableExplicit
Global program
Global Exitcode.s

Procedure ProgramExists(program$)
  program=RunProgram("which", program$, "", #PB_Program_Open | #PB_Program_Error | #PB_Program_Read)
  
  If program
      While ProgramRunning(program)
      Exitcode = ReadProgramString(program)  
      Wend
      CloseProgram(program)
  EndIf
  
  If Exitcode <> ""
        ProcedureReturn #True
      Else
        ProcedureReturn #False        
  EndIf
EndProcedure

If ProgramExists("openssl")
  Debug "Program existiert"
Else
  Debug "Programm existiert nicht"
EndIf
Wenn einem die einfachen Dinge net einfallen, klappt's meistens umständlich...
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: Test ob ein Programm installiert ist

Beitrag von #NULL »

Du überschreibst Exitcode jedesmal, lieber anhängen:

Code: Alles auswählen

Procedure ProgramExists(program$)
  Exitcode = ""
  ...
      Exitcode + ReadProgramString(program) 
Vielleicht solltest du vorher auch jedesmal AvailableProgramOutput() überprüfen.
Im Übrigen funktionieren bei mir beide Varianten, Ich würde aber ProgramExitCode() bevorzugen.
my pb stuff..
Bild..jedenfalls war das mal so.
Sommertv
Beiträge: 68
Registriert: 26.04.2019 10:31
Computerausstattung: Lenovo W500, Debian Stable, Purebasic 5.70 (momentan die Testversion)
Wohnort: Mühldorf am Inn

Re: Test ob ein Programm installiert ist

Beitrag von Sommertv »

Danke, das mit der Variable löschen werd ich berücksichtigen...
Obige Variante funktioniert bei mir nicht mit which, mit whereis schon... seltsam...
Finde dass whereis besser geeignet ist, weil which nur nach Executable sucht.

Dank und schöne Grüsse
Kurt
Wenn einem die einfachen Dinge net einfallen, klappt's meistens umständlich...
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: Test ob ein Programm installiert ist

Beitrag von #NULL »

was gibt denn which openssl und whereis openssl im terminal aus? Wenn du keine binary hast aber z.B. eine include, dann gibt dir which nichts zurück, whereis aber schon.
my pb stuff..
Bild..jedenfalls war das mal so.
Sommertv
Beiträge: 68
Registriert: 26.04.2019 10:31
Computerausstattung: Lenovo W500, Debian Stable, Purebasic 5.70 (momentan die Testversion)
Wohnort: Mühldorf am Inn

Re: Test ob ein Programm installiert ist

Beitrag von Sommertv »

which gibt aus:
/usr/bin/openssl

whereis:
openssl: /usr/bin/openssl /usr/include/openssl /usr/share/man/man1/openssl.1ssl.gz

Geht auch darum, fehlende oder Versionen einer lib zu erkennen und den Benutzer aufzufordern die richtige nachzuinstallieren.
whereis gibt bei nicht gefunden trotzdem z.B. "Topenssl:" aus, also muss ich den den Ausgabestring im einfachsten Fall mit len auswerten...
Wenn einem die einfachen Dinge net einfallen, klappt's meistens umständlich...
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: Test ob ein Programm installiert ist

Beitrag von #NULL »

Was funktioniert denn bei Programies Variante nicht? Wenn es an IsProgram() liegt, dann versuche mal den vollen Pfad für which anzugeben, also z.B. /usr/bin/which.
my pb stuff..
Bild..jedenfalls war das mal so.
Sommertv
Beiträge: 68
Registriert: 26.04.2019 10:31
Computerausstattung: Lenovo W500, Debian Stable, Purebasic 5.70 (momentan die Testversion)
Wohnort: Mühldorf am Inn

Re: Test ob ein Programm installiert ist

Beitrag von Sommertv »

Hallo,
du hattest Recht... mit /usr/bin/which funktioniert es einwandfrei. :D
Mit whereis kommt aber immer True zurück, auch wenn die Datei gar nicht existiert. Mit Programies Variante kann ich leider den Rückgabestring nicht auswerten, weil #PB_Program_Wait und #PB_Program_Read nicht miteinander kombinierbar ist.
Hab jetzt meine Version so abgeändert:

Code: Alles auswählen

EnableExplicit
Global program
Global Exitcode.s
Global program$

Procedure ProgramExists(program$)
  program=RunProgram("whereis", program$, "", #PB_Program_Open | #PB_Program_Error | #PB_Program_Read)
  Exitcode=""
  If program
      While ProgramRunning(program)
      Exitcode= ReadProgramString(program)  
      Wend
      CloseProgram(program)
  EndIf
  
  If Len(Exitcode) > 1+Len(program$)
        ProcedureReturn #True
      Else
        ProcedureReturn #False        
  EndIf
EndProcedure

program$="liblrdf.so.0"
If ProgramExists(program$)
  Debug program$ + " existiert"
Else
  Debug program$ + " existiert nicht"
EndIf
Wenn einem die einfachen Dinge net einfallen, klappt's meistens umständlich...
Benutzeravatar
Programie
Beiträge: 1280
Registriert: 06.08.2005 22:56
Computerausstattung: https://www.sysprofile.de/id160800
Wohnort: Gernsbach
Kontaktdaten:

Re: Test ob ein Programm installiert ist

Beitrag von Programie »

Noch ein kleiner Tipp am Rande: Nicht alle Variablen global deklarieren! Das kann schnell zu komischen Effekten führen wenn man innerhalb einer Procedure eine Variable überschreibt und diese dann außerhalb der Procedure auch abgeändert wird, da sie global ist.

Im Normalfall sollte man Variablen, welche nur innerhalb einer Procedure benötigt werden, als Protected deklarieren.

Das Beispiel von Sommertv würde ich so anpassen:

Code: Alles auswählen

EnableExplicit

Procedure ProgramExists(program$)
  Protected program=RunProgram("whereis", program$, "", #PB_Program_Open | #PB_Program_Error | #PB_Program_Read)
  Protected Exitcode.s=""
  If program
      While ProgramRunning(program)
      Exitcode= ReadProgramString(program) 
      Wend
      CloseProgram(program)
  EndIf
 
  If Len(Exitcode) > 1+Len(program$)
        ProcedureReturn #True
      Else
        ProcedureReturn #False       
  EndIf
EndProcedure

Define program$="liblrdf.so.0"
If ProgramExists(program$)
  Debug program$ + " existiert"
Else
  Debug program$ + " existiert nicht"
EndIf
Oder alternativ eine Variante welche auch schaut, ob nach dem ":" in der Ausgabe von whereis wirklich etwas steht:

Code: Alles auswählen

EnableExplicit

Procedure ProgramExists(program$)
  Protected program = RunProgram("whereis", program$, "", #PB_Program_Open | #PB_Program_Read)
  Protected output$ = ""
  Protected paths$

  If program
    While ProgramRunning(program)
      output$ + ReadProgramString(program)
    Wend
    CloseProgram(program)
  EndIf

  ; output$ wenn program$ existiert:
  ; sh: /bin/sh /bin/sh.distrib /usr/share/man/man1/sh.1.gz
  ; output$ wenn program$ nicht existiert:
  ; foo:
  paths$ = Trim(StringField(output$, 2, ":"))

  ; paths$ is leer wenn program$ nicht existiert (keine Zeichen hinter ":")
  If Len(paths$)
    ProcedureReturn #True
  Else
    ProcedureReturn #False       
  EndIf
EndProcedure

Define program$="sh"
If ProgramExists(program$)
  Debug program$ + " existiert"
Else
  Debug program$ + " existiert nicht"
EndIf
Da der erwartete Output schon im Standardoutput steht, kann man auf das #PB_Program_Error Flag bei RunProgram() verzichten.
BildBildBildBild
Antworten