Was macht
echo $?
meine in der Shell-Programmierung?
Was macht
echo $?
meine in der Shell-Programmierung?
Antworten:
Dies ist der Exit-Status des zuletzt ausgeführten Befehls.
Beispielsweise gibt der Befehl true
immer den Status von 0
und false
immer den Status von zurück 1
:
true
echo $? # echoes 0
false
echo $? # echoes 1
Aus dem Handbuch: (zugänglich durch Aufrufen man bash
Ihrer Shell)
$?
Wird auf den Exit-Status der zuletzt ausgeführten Vordergrund-Pipeline erweitert.
Konventionell bedeutet ein Exit-Status 0
Erfolg, und ein Rückgabestatus ungleich Null bedeutet Misserfolg. Weitere Informationen zu Exit-Status finden Sie auf Wikipedia .
Es gibt andere spezielle Variablen wie diese, wie Sie in diesem Online-Handbuch sehen können: https://www.gnu.org/s/bash/manual/bash.html#Special-Parameters
$
und ?
sind zwei unterschiedliche Parameter und $?
erscheinen nicht in der Bash (1) Manpage.
$?
Gibt den Exit-Wert des zuletzt ausgeführten Befehls zurück. echo $?
druckt diesen Wert auf der Konsole. Null bedeutet eine erfolgreiche Ausführung, während Werte ungleich Null verschiedenen Fehlerursachen zugeordnet werden.
Daher beim Scripting; Ich neige dazu, die folgende Syntax zu verwenden
if [ $? -eq 0 ]; then
# do something
else
# do something else
fi
Der Vergleich ist gleich 0
oder nicht gleich durchzuführen 0
.
** Update Basierend auf dem Kommentar: Idealerweise sollten Sie den obigen Codeblock nicht zum Vergleich verwenden. Weitere Informationen finden Sie in den Kommentaren und Erläuterungen zu @tripleee.
cmd; if [ $? -eq 0 ]; then
sollte überarbeitet werden if cmd; then
. Der eigentliche Zweck von if
(und den anderen Flusssteuerungsanweisungen in der Shell) besteht darin, einen Befehl auszuführen und seinen Beendigungsstatus zu überprüfen.
if cmd;
Möglicherweise sind einige Bedingungen nicht sehr gut lesbar, insbesondere wenn cmd auf ein anderes Skript verweist.
[ 1 ]
und [ 0 ]
sind beide wahr; [
ohne Operator prüft, ob das Argument eine nicht leere Zeichenfolge ist.
vendor/bin/drush status bootstrap | grep -q $(vendor/bin/drush php-eval 'if (function_exists("t")) echo t("Successful");') &> /dev/null;
. Wenn ich das in eine einzige Zeile setzen if [ ... ]
müsste, wäre es furchtbar unlesbar. Ich habe vor, die Ausgabe dieser Zeile in einer Variablen zu speichern, damit ich es if [ $drupal_installed -eq 0 ]
später noch sagen kann .
echo $? - Gibt den EXIT STATUS des zuletzt ausgeführten Befehls an . Dieser EXIT-STATUS ist höchstwahrscheinlich eine Zahl, bei der NULL Erfolg bedeutet und jeder NON-ZERO-Wert Fehler anzeigt
? - Dies ist ein spezieller Parameter / eine spezielle Variable in Bash.
$? - Es gibt den in der Variablen "?" Gespeicherten Wert an.
Einige ähnliche spezielle Parameter in BASH sind 1,2, *, # (normalerweise im Echo-Befehl als $ 1, $ 2, $ *, $ # usw. zu sehen).
Es hat den letzten Statuscode (Exit-Wert) eines Befehls.
Beispiel für einen minimalen POSIX C-Exit-Status
Um dies zu verstehen $?
, müssen Sie zuerst das Konzept des Prozess-Exit-Status verstehen, das von POSIX definiert wird . Unter Linux:
Wenn ein Prozess den exit
Systemaufruf aufruft , speichert der Kernel den an den Systemaufruf übergebenen Wert (anint
) übergebenen auch nachdem der Prozess beendet ist.
Der Exit - Systemaufruf wird durch die genannte exit()
ANSI - C - Funktion, und indirekt , wenn Sie tun , return
aus main
.
Der Prozess, der den Prozess "Exiting Child" (Bash) aufgerufen hat, häufig mit fork
+ exec
, kann den Exit-Status des Kindes mit dem wait
Systemaufruf abrufen
Betrachten Sie den Bash-Code:
$ false
$ echo $?
1
Das C "Äquivalent" ist:
false.c
#include <stdlib.h> /* exit */
int main(void) {
exit(1);
}
bash.c
#include <unistd.h> /* execl */
#include <stdlib.h> /* fork */
#include <sys/wait.h> /* wait, WEXITSTATUS */
#include <stdio.h> /* printf */
int main(void) {
if (fork() == 0) {
/* Call false. */
execl("./false", "./false", (char *)NULL);
}
int status;
/* Wait for a child to finish. */
wait(&status);
/* Status encodes multiple fields,
* we need WEXITSTATUS to get the exit status:
* http://stackoverflow.com/questions/3659616/returning-exit-code-from-child
**/
printf("$? = %d\n", WEXITSTATUS(status));
}
Kompilieren und ausführen:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o bash bash.c
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o false false.c
./bash
Ausgabe:
$? = 1
Wenn Sie in Bash die Eingabetaste drücken, geschieht eine Gabelung + Exec + Wait wie oben, und Bash wird dann gesetzt $?
auf den Exit-Status des Forked-Prozesses.
Hinweis: Für integrierte Befehle wie echo
muss kein Prozess erzeugt werden, und Bash wird nur festgelegt$?
auf 0 gesetzt, um einen externen Prozess zu simulieren.
Standards und Dokumentation
POSIX 7 2.5.2 "Spezielle Parameter" http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02 :
? Wird auf den dezimalen Exit-Status der letzten Pipeline erweitert (siehe Pipelines).
man bash
"Spezielle Parameter":
Die Shell behandelt mehrere Parameter speziell. Auf diese Parameter darf nur verwiesen werden. eine Zuordnung zu ihnen ist nicht zulässig. [...]
? Wird auf den Exit-Status der zuletzt ausgeführten Vordergrund-Pipeline erweitert.
ANSI C und POSIX empfehlen dann Folgendes:
0
bedeutet, dass das Programm erfolgreich war
andere Werte: Das Programm ist irgendwie fehlgeschlagen.
Der genaue Wert kann die Art des Fehlers angeben.
ANSI C definiert nicht die Bedeutung von Vaues, und POSIX gibt Werte größer als 125 an: Was bedeutet "POSIX"?
Bash verwendet den Exit-Status für if
In Bash verwenden wir den Exit-Status häufig $?
implizit, um if
Anweisungen wie folgt zu steuern :
if true; then
:
fi
Wo true
ist ein Programm, das nur 0 zurückgibt.
Das Obige entspricht:
true
result=$?
if [ $result = 0 ]; then
:
fi
Und in:
if [ 1 = 1 ]; then
:
fi
[
ist nur ein Programm mit einem seltsamen Namen (und einem integrierten Bash, der sich so verhält) und 1 = 1 ]
seinen Argumenten, siehe auch: Unterschied zwischen einfachen und doppelten eckigen Klammern in Bash
Von http://www.gnu.org/s/bash/manual/bash.html#Special-Parameters
?
Expands to the exit status of the most recently executed foreground pipeline.
Siehe das Bash-Handbuch unter 3.4.2 Spezielle Parameter :
? - Wird auf den Exit-Status der zuletzt ausgeführten Vordergrund-Pipeline erweitert.
Es ist etwas schwer zu finden, da es nicht als aufgeführt ist $?
(der Variablenname ist "nur" ?
). Siehe natürlich auch den Exit-Status- Abschnitt ;-)
Viel Spaß beim Codieren.