Seite 1 von 2

Test ob ein Programm installiert ist

Verfasst: 28.06.2019 22:23
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

Re: Test ob ein Programm installiert ist

Verfasst: 29.06.2019 14:13
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

Re: Test ob ein Programm installiert ist

Verfasst: 30.06.2019 10:45
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

Re: Test ob ein Programm installiert ist

Verfasst: 30.06.2019 11:09
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.

Re: Test ob ein Programm installiert ist

Verfasst: 30.06.2019 11:43
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

Re: Test ob ein Programm installiert ist

Verfasst: 30.06.2019 12:00
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.

Re: Test ob ein Programm installiert ist

Verfasst: 30.06.2019 12:26
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...

Re: Test ob ein Programm installiert ist

Verfasst: 30.06.2019 20:02
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.

Re: Test ob ein Programm installiert ist

Verfasst: 30.06.2019 20:48
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

Re: Test ob ein Programm installiert ist

Verfasst: 30.06.2019 21:56
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.