Voir les exemples suivants et leurs sorties dans des shells POSIX:
false;echo $?
oufalse || echo 1
:1
false;foo="bar";echo $?
oufoo="bar" && echo 0
:0
foo=$(false);echo $?
oufoo=$(false) || echo 1
:1
foo=$(true);echo $?
oufoo=$(true) && echo 0
:0
Comme mentionné par la réponse la plus votée sur /programming/6834487/what-is-the-variable-in-shell-scripting :
$?
est utilisé pour trouver la valeur de retour de la dernière commande exécutée.
C'est probablement un peu trompeur dans ce cas, alors obtenons la définition POSIX qui est également citée dans un article de ce thread:
? Se développe au statut de sortie décimal du pipeline le plus récent (voir Pipelines).
Il semble donc que l'affectation elle-même compte comme une commande (ou plutôt comme une partie de pipeline) avec une valeur de sortie nulle mais qui s'applique avant le côté droit de l'affectation (par exemple, la substitution de commandes appelle dans mes exemples ici).
Je vois comment ce comportement est logique d'un point de vue pratique, mais il me semble quelque peu inhabituel que l'affectation elle-même compte dans cet ordre. Peut-être pour expliquer plus clairement pourquoi c'est étrange pour moi, supposons que l'affectation était une fonction:
ASSIGNMENT( VARIABLE, VALUE )
alors foo="bar"
serait
ASSIGNMENT( "foo", "bar" )
et foo=$(false)
serait quelque chose comme
ASSIGNMENT( "foo", EXECUTE( "false" ) )
ce qui signifierait que les EXECUTE
exécutions en premier et ensuite ASSIGNMENT
sont exécutées mais c'est toujours le EXECUTE
statut qui compte ici.
Suis-je correct dans mon évaluation ou ai-je un malentendu / manque quelque chose? Est-ce que ce sont les bonnes raisons pour lesquelles je considère ce comportement comme "étrange"?
false;foo="bar";echo $?
retourne toujours 0 quand la dernière vraie commande qui a été exécutéefalse
?" C'est fondamentalement que les affectations se comportent de manière spéciale en ce qui concerne les codes de sortie. Leur code de sortie est toujours 0, sauf quand ce n'est pas à cause de quelque chose qui s'est déroulé dans le côté droit de l'affectation.Réponses:
Le statut de sortie des affectations est étrange . La manière la plus évidente pour une affectation d'échouer est si la variable cible est marquée
readonly
.Notez que ni les chemins vrai ni faux de l'instruction if n'ont été pris, l'affectation échouant a arrêté l'exécution de l'instruction entière. bash en mode POSIX et ksh93 et zsh abandonneront tous un script si une affectation échoue.
Pour citer la norme POSIX à ce sujet :
C'est exactement la partie de la grammaire shell impliquée dans
qui provient d'un
simple_command
(simple_command → cmd_prefix → ASSIGNMENT_WORD). Ainsi, si une affectation réussit, l'état de sortie est nul, sauf si une substitution de commande a été impliquée, auquel cas l'état de sortie est l'état de la dernière. Si l'affectation échoue, l'état de sortie est différent de zéro, mais vous ne pourrez peut-être pas l'attraper.la source
Vous dites,
Ce n'est pas une façon terrible de voir les choses. Mais c'est une légère simplification excessive. Le statut de retour global de
est l'état de sortie de . L' affectation qui se produit après l' affectation ne définit pas l'état de sortie global sur 0.cmd4
E=
D=
De plus, comme le souligne icarus , les variables peuvent être définies en lecture seule. Considérez la variation suivante sur l'exemple d'icarus:
Même s'il
A
est en lecture seule, bash exécute la substitution de commande à droite deA=
- puis abandonne la commande car ilA
est en lecture seule. Cela contredit en outre votre interprétation selon laquelle la valeur de sortie de l'affectation s'applique avant le côté droit de l'affectation.la source