3131 Stimmen

Wie kann ich von einem Bash-Skript aus prüfen, ob ein Programm existiert?

Wie kann ich überprüfen, ob ein Programm existiert, und zwar so, dass es entweder einen Fehler zurückgibt und beendet wird oder mit dem Skript fortfährt?

Es sollte eigentlich ganz einfach sein, aber es hat mich nicht weitergebracht.

2 Stimmen

Was ist ein "Programm"? Beinhaltet es Funktionen und Aliasnamen? which gibt für diese den Wert true zurück. type ohne Argumente gibt zusätzlich true für reservierte Wörter und Shell-Builtins zurück. Wenn "Programm" bedeutet "auswählbar in $PATH ", dann siehe diese Antwort .

0 Stimmen

@TomHale Es hängt davon ab, welche Implementierung von which die Sie verwenden; diese wird nicht von der Bash, sondern z.B. von Debian's debianutils bereitgestellt.

15voto

0xF Punkte 2553

Wenn Sie prüfen, ob ein Programm vorhanden ist, werden Sie es wahrscheinlich sowieso später ausführen. Warum versuchen Sie nicht, es überhaupt zu starten?

if foo --version >/dev/null 2>&1; then
    echo Found
else
    echo Not found
fi

Es ist eine vertrauenswürdigere Überprüfung, dass das Programm läuft, als wenn man nur die PATH-Verzeichnisse und Dateiberechtigungen überprüft.

Außerdem können Sie einige nützliche Ergebnisse von Ihrem Programm erhalten, z. B. seine Version.

Der Nachteil ist natürlich, dass manche Programme schwer zu starten sind und manche keine --version Option, um das Programm sofort (und erfolgreich) zu beenden.

12voto

todd_dsm Punkte 740

Es könnte einfacher sein, nur:

#!/usr/bin/env bash                                                                
set -x                                                                             

# if local program 'foo' returns 1 (doesn't exist) then...                                                                               
if ! type -P foo; then                                                             
    echo 'crap, no foo'                                                            
else                                                                               
    echo 'sweet, we have foo!'                                                    
fi                                                                                 

Ändern Sie foo a vi um die andere Bedingung zum Auslösen zu bringen.

0 Stimmen

Ich habe es absichtlich so einfach wie möglich gemacht. Die einzige Möglichkeit, dass es nicht funktioniert, wäre wahrscheinlich, den Namen des Programms falsch einzugeben. Abgesehen davon sollte es unter allen Bedingungen funktionieren.

0 Stimmen

Warum haben Sie das Drucken von Befehlen als ausgeführt aktiviert? ( set -x )

0 Stimmen

set -x ist der Bash-Debugger. Er hilft zu veranschaulichen, was vor sich geht, wenn Leute einfach eine Lösung von Seiten wie dieser kopieren/einfügen->ausführen; das ist alles. Kommentieren/Löschen Sie die Zeile, wenn Sie mit der Fehlersuche fertig sind.

10voto

Prüfung auf Mehrfachabhängigkeiten und Information der Endnutzer über den Status

for cmd in latex pandoc; do
  printf '%-10s' "$cmd"
  if hash "$cmd" 2>/dev/null; then
    echo OK
  else
    echo missing
  fi
done

Beispielhafte Ausgabe:

latex     OK
pandoc    missing

Einstellen der 10 auf die maximale Befehlslänge. Dies geschieht nicht automatisch, denn ich sehe keine nicht-verbale POSIX-Methode, um dies zu tun: Wie kann ich die Spalten einer durch Leerzeichen getrennten Tabelle in Bash ausrichten?

Prüfen Sie, ob einige apt Pakete werden installiert mit dpkg -s und installieren Sie sie andernfalls .

Siehe: Prüfen Sie, ob ein apt-get-Paket installiert ist, und installieren Sie es, falls nicht, unter Linux

Es wurde bereits erwähnt unter: Wie kann ich von einem Bash-Skript aus prüfen, ob ein Programm existiert?

2 Stimmen

Nicht-verbale Methode: 1) Entfernen Sie den width specifier; 2) fügen Sie ein Leerzeichen nach dem printf des Befehlsnamens ein; 3) leiten Sie die for-Schleife nach column -t (Teil von util-linux).

7voto

Magnus Punkte 21152

Ich habe die vorherigen Antworten auf der Box, zu der ich Zugang habe, nie zum Laufen gebracht. Zum einen, type installiert worden ist (was die more tut). Daher wird die Built-in-Richtlinie benötigt. Dieser Befehl funktioniert bei mir:

if [ `builtin type -p vim` ]; then echo "TRUE"; else echo "FALSE"; fi

4 Stimmen

Die Klammern sind nicht Teil der if Syntax, verwenden Sie einfach if builtin type -p vim; then ... . Und die Backticks sind eine wirklich alte und veraltete Syntax, $() wird sogar unterstützt von sh auf allen modernen Systemen.

0 Stimmen

@nyuszika7h Aber diese Tests können fehlschlagen: Zum Beispiel builtin type -p if gibt nichts aus und gibt 0 zurück, egal ob if existiert.

0 Stimmen

@jarno Was ist Ihr Argument? Wie Sie sagen, es beide nichts aus und gibt 0 zurück, daher macht es keinen Unterschied, ob Sie if builtin type -p if o if [ `builtin type -p if` ] , mit der Ausnahme, dass letztere unnötig langatmig ist und eine veraltete Syntax verwendet.

7voto

Richard A Quadling Punkte 3356

Ich wollte die gleiche Frage beantwortet haben, aber innerhalb eines Makefiles ausführen.

install:
    @if [[ ! -x "$(shell command -v ghead)" ]]; then \
        echo 'ghead does not exist. Please install it.'; \
        exit -1; \
    fi

1 Stimmen

Verlässt sich auf Bash als Shell aufgrund der Verwendung von [[ .

1 Stimmen

使用方法 $(shell ...) innerhalb eines Rezeptes ist fast immer falsch. Die akzeptierte Antwort funktioniert gut in einem Makefile auch. exit -1 ist nicht klar definiert und die Bedingung ist ohnehin nutzlos.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X