Ich habe folgendes Skript erstellt:
# !/bin/bash
# OUTPUT-COLORING
red='\e[0;31m'
green='\e[0;32m'
NC='\e[0m' # No Color
# FUNCTIONS
# directoryExists - Does the directory exist?
function directoryExists {
cd $1
if [ $? = 0 ]
then
echo -e "${green}$1${NC}"
else
echo -e "${red}$1${NC}"
fi
}
# EXE
directoryExists "~/foobar"
directoryExists "/www/html/drupal"
Das Skript funktioniert, aber neben meinen Echos gibt es auch die Ausgabe wann
cd $1
schlägt bei der Ausführung fehl.
testscripts//test_labo3: line 11: cd: ~/foobar: No such file or directory
Ist es möglich, das zu fangen?
bash
shell
shell-script
error-handling
Thomas De Wilde
quelle
quelle
test -d /path/to/directory
(oder[[ -d /path/to/directory ]]
in der Bash) wird Ihnen sagen, ob ein bestimmtes Ziel ein Verzeichnis ist oder nicht, und es wird es leise tun.cd
.directoryExists
.Antworten:
Ihr Skript ändert Verzeichnisse während der Ausführung, was bedeutet, dass es nicht mit einer Reihe relativer Pfadnamen funktioniert. Sie haben dann später kommentiert, dass Sie nur auf das Vorhandensein eines Verzeichnisses prüfen möchten, nicht auf die Verwendbarkeit
cd
, sodass Antworten überhaupt nicht verwendet werden müssencd
. Überarbeitet. Verwendungtput
und Farben vonman terminfo
:(Bearbeitet, um das Unverwundbarere
printf
anstelle des Problems zu verwendenecho
, das bei Escape-Sequenzen im Text auftreten kann.)quelle
Dient
set -e
zum Festlegen des Exit-On-Error-Modus: Wenn ein einfacher Befehl einen Status ungleich Null zurückgibt (was auf einen Fehler hinweist), wird die Shell beendet.Beachten Sie, dass
set -e
nicht immer in nicht kicken. Befehle in Testpositionen dürfen nicht (zBif failing_command
,failing_command || fallback
). Befehle in der Subshell führen nur zum Verlassen der Subshell, nicht der übergeordneten:set -e; (false); echo foo
Displaysfoo
.Alternativ oder zusätzlich können Sie in bash (und ksh und zsh, aber nicht plain sh) einen Befehl angeben, der ausgeführt wird, falls ein Befehl einen Nicht-Null-Status zurückgibt, mit dem
ERR
Trap, ztrap 'err=$?; echo >&2 "Exiting on error $err"; exit $err' ERR
. Beachten Sie, dass in solchen Fällen(false); …
die ERR-Trap in der Subshell ausgeführt wird, sodass das übergeordnete Element nicht beendet werden kann.quelle
||
zum Beheben von Fehlern gefunden, mit der sich Fehler problemlos und ohne Verwendung von Traps beheben lassen . Siehe meine Antwort . Was denkst du über diese Methode?ERR
Pseudosignale in allen wichtigen Shells unterstützt werden. Danke für die Bewertung! =)So erweitern Sie die Antwort von @Gilles :
Funktioniert in der Tat
set -e
nicht in Befehlen, wenn Sie||
Operator nach ihnen verwenden, selbst wenn Sie sie in einer Subshell ausführen. zB würde das nicht funktionieren:Der
||
Bediener muss jedoch verhindern, dass die äußere Funktion vor der Bereinigung wiederhergestellt wird.Es gibt einen kleinen Trick, der verwendet werden kann, um dies zu beheben: Führen Sie den inneren Befehl im Hintergrund aus und warten Sie dann sofort darauf. Der
wait
eingebaute Code gibt den Exit-Code des inneren Befehls zurück. Jetzt verwenden Sie||
afterwait
, nicht die innere Funktion, undset -e
funktioniert in letzterer ordnungsgemäß:Hier ist die generische Funktion, die auf dieser Idee aufbaut. Es sollte in allen POSIX-kompatiblen Shells funktionieren, wenn Sie
local
Schlüsselwörter entfernen , dh allelocal x=y
durch Folgendes ersetzenx=y
:Anwendungsbeispiel:
Beispiel ausführen:
Das einzige, was Sie beachten müssen, wenn Sie diese Methode verwenden, ist, dass alle Änderungen an Shell-Variablen, die Sie mit dem übergebenen Befehl vornehmen,
run
nicht an die aufrufende Funktion weitergegeben werden, da der Befehl in einer Subshell ausgeführt wird.quelle
Sie sagen nicht genau, was Sie mit
catch
--- melden und fortfahren meinen ; weitere Bearbeitung abbrechen?Da bei
cd
einem Fehler ein Status ungleich Null zurückgegeben wird, können Sie Folgendes tun:Sie können einfach bei einem Fehler beenden:
Oder geben Sie Ihre eigene Nachricht wieder und beenden Sie das Programm:
Und / oder unterdrücken Sie den Fehler, der bei einem Fehler
cd
auftritt:Standardmäßig sollten Befehle Fehlermeldungen in STDERR (Dateideskriptor 2) einfügen. So
2>/dev/null
heißt die Umleitung von STDERR auf den "Bit-Bucket", den man kennt/dev/null
.(Vergessen Sie nicht, Ihre Variablen anzugeben und das Ende der Optionen für anzugeben.
cd
)quelle
Eigentlich würde ich für Ihren Fall sagen, dass die Logik verbessert werden kann.
Anstelle von cd und überprüfe, ob es existiert, überprüfe, ob es existiert, und gehe dann in das Verzeichnis.
Wenn Sie jedoch die möglichen Fehler ausschließen möchten
cd -- "$1" 2>/dev/null
, wird dies das Debuggen in Zukunft erschweren. Sie können überprüfen, ob Flags getestet wurden unter: Bash if documentation :quelle
$1
Variable nicht in Anführungszeichen und schlägt fehl, wenn diese Variable Leerzeichen oder andere Shell-Metazeichen enthält. Es wird auch nicht geprüft, ob der Benutzer die Berechtigung dazucd
hat.