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.
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.
Die Bereitschaft, zu lernen und sich zu verbessern, muss belohnt werden. +1 Das ist klar und einfach. Das Einzige, was ich hinzufügen kann, ist, dass command
gelingt auch bei Aliasen, was vielleicht etwas kontraintuitiv ist. Die Prüfung auf Existenz in einer interaktiven Shell wird andere Ergebnisse liefern, als wenn man sie in ein Skript verschiebt.
Ich habe gerade getestet und mit shopt -u expand_aliases
ignoriert/versteckt Aliasnamen (wie die alias ls='ls -F'
in einer anderen Antwort erwähnt) und shopt -s expand_aliases
löst sie auf über command -v
. Vielleicht sollte sie also vor der Prüfung gesetzt und danach wieder aufgehoben werden, obwohl sie den Rückgabewert der Funktion beeinflussen könnte, wenn Sie die Ausgabe des Befehlsaufrufs nicht explizit erfassen und zurückgeben.
Warum funktioniert das nicht bei if exists conda; then
auch wenn anaconda installiert ist und zurückkehrt: usage: conda [-h] [-V] command...
wenn man eintritt conda
im Terminal? (Hinweis: Ich habe überprüft, dass Ihre Antwort mit if exists bash; then
auf einem Ubuntu 20 Betriebssystem).
Versuchen Sie es mit:
test -x filename
o
[ -x filename ]
Aus der Bash-Manpage unter Bedingte Ausdrücke :
-x file True if file exists and is executable.
Zur Verwendung hash
, wie @lhunath vorschlägt in einem Bash-Skript:
hash foo &> /dev/null
if [ $? -eq 1 ]; then
echo >&2 "foo not found."
fi
Dieses Skript läuft hash
und prüft dann, ob der Exit-Code des letzten Befehls, der Wert, der in $?
ist gleich 1
. Wenn hash
findet nicht foo
wird der Exit-Code sein 1
. Wenn foo
vorhanden ist, lautet der Exit-Code 0
.
&> /dev/null
leitet um. Standardfehler y Standardausgabe von hash
so dass sie nicht auf dem Bildschirm erscheint und echo >&2
schreibt die Nachricht in den Standardfehler.
Befehl -v
funktioniert gut, wenn die Option POSIX_BUILTINS für die <command>
zu testen, aber es kann fehlschlagen, wenn nicht. (Bei mir hat es jahrelang funktioniert, aber vor kurzem bin ich auf einen Fall gestoßen, in dem es nicht funktioniert hat).
Ich halte das Folgende für ausfallsicherer:
test -x "$(which <command>)"
Denn es testet auf drei Dinge: Pfad, Existenz und Ausführungserlaubnis.
Funktioniert nicht. test -x $(which ls)
gibt 0 zurück, ebenso wie die test -x $(which sudo)
auch wenn ls
installiert und lauffähig ist und sudo
ist nicht einmal in dem Docker-Container installiert, in dem ich arbeite.
@algal Ich glaube, Sie müssen Anführungszeichen verwenden, also test -x "$(which <command>)"
@algal Vielleicht ls
ein Alias ist? Ich glaube nicht, dass es funktionieren würde, wenn der Befehl Parameter hat.
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.
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.
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 .1 Stimmen
Ebenfalls relevant ist Wie kann man mit 'hash -r' alle Shells aktualisieren? y Wann sollen ausführbare Dateien in $PATH mit der Bash aufbereitet werden?
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.