Veja os exemplos a seguir e suas saídas nos 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
Conforme mencionado pela resposta mais votada em /programming/6834487/what-is-the-variable-in-shell-scripting :
$?
é usado para encontrar o valor de retorno do último comando executado.
Isso provavelmente é um pouco enganador nesse caso, então vamos obter a definição POSIX, que também é citada em um post desse segmento:
? Expande para o status de saída decimal do pipeline mais recente (consulte Pipelines).
Portanto, parece que uma atribuição em si conta como um comando (ou melhor, como uma parte do pipeline) com um valor de saída zero, mas que se aplica antes do lado direito da atribuição (por exemplo, a substituição de comando chama nos meus exemplos aqui).
Vejo como esse comportamento faz sentido do ponto de vista prático, mas me parece um pouco incomum que a tarefa em si contaria nessa ordem. Talvez para deixar mais claro por que isso é estranho para mim, vamos assumir que a tarefa era uma função:
ASSIGNMENT( VARIABLE, VALUE )
então foo="bar"
seria
ASSIGNMENT( "foo", "bar" )
e foo=$(false)
seria algo como
ASSIGNMENT( "foo", EXECUTE( "false" ) )
o que significa que as EXECUTE
execuções são executadas primeiro e somente depois, ASSIGNMENT
mas ainda é o EXECUTE
status que importa aqui.
Estou correto na minha avaliação ou estou entendendo errado / faltando alguma coisa? Essas são as razões certas para eu ver esse comportamento como "estranho"?
false;foo="bar";echo $?
sempre retorna 0 quando o último comando real executado foi false
?" É basicamente que as atribuições se comportam de maneira especial quando se trata de códigos de saída. Seu código de saída é sempre 0, exceto quando não é por causa de algo que foi executado como parte do lado direito da tarefa.