2013-11-23 8 views
32

Ich bin verwirrt, was Fehlercode der Befehl zurückkehrt, wenn eine variable Zuordnung eindeutig und mit dem Befehl Substitution Ausführung:Bash: Exit-Code von Variablenzuweisung zu befehlen Substitution

a=$(false); echo $? 

Es gibt 1, die mich denken lassen Diese Variablenzuweisung wird nicht ausgeführt oder erzeugt bei der letzten einen neuen Fehlercode. Aber wenn ich versucht, dies:

false; a=""; echo $? 

Es 0 gibt, offensichtlich ist es das, was a="" zurückkehrt und sie überschreiben 1 zurück von false.

Ich möchte wissen, warum dies passiert, gibt es eine Besonderheit in der Variablenzuweisung, die sich von anderen normalen Befehlen unterscheidet? Oder nur weil a=$(false) als ein einziger Befehl betrachtet wird und nur Befehlsersatzteil sinnvoll ist?

- UPDATE -

Vielen Dank allen, von den Antworten und Kommentare ich den Punkt bekam „Wenn Sie eine Variable zuweisen mit dem Befehl Substitution, ist der Exit-Status der Status des Befehls“ (von @Barmar), diese Erklärung ist hervorragend klar und leicht zu verstehen, aber sprechen nicht genau genug für Programmierer, ich möchte die Bezugnahme auf diesen Punkt von Behörden wie TLDP oder GNU man page sehen, bitte helfen Sie mir, es zu finden raus, danke nochmal!

+0

TLDP ist * nicht * eine maßgebliche Quelle - das ABS ist geradezu berüchtigt dafür, schlechte Praktiken in bash zu zeigen, so wie w3schools in der JavaScript-Welt. –

Antwort

44

Nach Ausführung eines Befehls als $(command) ermöglicht die output of the command to replace itself.

Wenn Sie sagen:

a=$(false)    # false fails; the output of false is stored in the variable a 

die Ausgabe durch den Befehl erzeugt false wird in der Variablen a gespeichert. Außerdem ist der Exit-Code der gleiche wie der Befehl. help false würde sagen:

false: false 
    Return an unsuccessful result. 

    Exit Status: 
    Always fails. 

Auf der anderen Seite, sagte:

$ false    # Exit code: 1 
$ a=""     # Exit code: 0 
$ echo $?    # Prints 0 

bewirkt, dass der Exit-Code für die Zuordnung zu a zurückgegeben werden, die 0 ist.


EDIT:

Zitiert aus den manual:

Wenn einer der Ausdehnungen einen Befehl Substitution enthielt, der Austritt Status des Befehls ist der Beendigungsstatus des letzten Befehls Substitution durchgeführt.

Zitiert aus BASHFAQ/002:

Wie kann ich den Rückgabewert speichern und/oder Ausgabe eines Befehls in einer Variable?

...

output=$(command)

status=$?

Die Zuordnung zu output hat keine Auswirkung auf command ‚s Exit-Status, die noch in $? ist.

+0

Sehr gute Antwort :)! Kannst du mir bitte helfen, die Referenz von 'der Exit-Code ist der gleiche wie durch den Befehl 'zu finden, ich verbrachte eine Menge Zeit, aber nicht das Ergebnis :( – Reorx

+0

@Reorx Hinzugefügt ein paar Referenzen in der Bearbeitung oben – devnull

+0

Danke, das ist klar genug: D – Reorx

0

(keine Antwort auf ursprüngliche Frage aber zu lang für einen Kommentar)

Beachten Sie, dass export A=$(false); echo $? Ausgänge 0! Offensichtlich gelten die in devnull's answer angeführten Regeln nicht mehr. So fügen Sie (meine Hervorhebung) ein wenig Kontext zu diesem Zitat:

3.7.1 Einfache Befehl Expansion

...

Wenn es einen Befehlsnamen nach der Expansion vorhanden ist, geht die Ausführung als beschrieben unter. Sonst, der Befehl wird beendet. Wenn eine der Erweiterungen eine Befehlsersetzung enthielt, ist der Beendigungsstatus des Befehls der Beendigungsstatus der letzten ausgeführten Befehlsersetzung. Wenn keine Befehlssubstitutionen vorhanden waren, wird der Befehl mit dem Status Null beendet.

3.7.2 Befehl Suchen und Ausführung [- das ist der "unten" Fall]

IIUC das Handbuch beschreibt var=foo als Sonderfall der var=foo command... Syntax (ziemlich verwirrend!). Die Regel "Exit-Status der letzten Befehlsersetzung" gilt nur für den Fall ohne Befehl.

Während es verlockend ist, an export var=foo als eine "modifizierte Zuweisungssyntax" zu denken, ist es nicht - export ist ein eingebauter Befehl (der zufälligerweise artikelähnliche Argumente entgegennimmt).

=> Wenn Sie eine var und Capture Befehl Substitution Status exportieren, es zu tun in 2 Stufen:

A=$(false) 
# ... check $? 
export A 

Auf diese Weise auch in set -e Modus arbeitet - tritt sofort, wenn der Befehl Substitution nicht-0 zurück .

Verwandte Themen