#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
imprime valor vazio. Eu esperava:
1
Por que a t1
variável não recebe o valor de retorno do comando exit - 1
?
#!/bin/bash
function0()
{
local t1=$(exit 1)
echo $t1
}
function0
echo
imprime valor vazio. Eu esperava:
1
Por que a t1
variável não recebe o valor de retorno do comando exit - 1
?
Respostas:
local t1=$(exit 1)
diz ao shell para:
exit 1
em um subshell;t1
, local para a função.Portanto, é normal que t1
acabe vazio.
( $()
é conhecido como substituição de comando .)
O código de saída é sempre atribuído a $?
, para que você possa
function0()
{
(exit 1)
echo "$?"
}
para obter o efeito que você está procurando. É claro que você pode atribuir $?
a outra variável:
function0()
{
(exit 1)
local t1=$?
echo "$t1"
}
$(trap 'printf "::ERRNO:$?"' 0; # now do whatever however
O código de saída foi armazenado em $? variável. Usando a Substituição de Comando captura apenas a saída, você deve usar (...) para criar o subshell :
#!/bin/bash
func() {
(exit 1)
local t1=$?
printf '%d\n' "$t1"
}
func
t1=$?
é usá-lo, não? e não seria $?
derrotado pela operação op? Eu acho que eu estou perguntando se ele não deve serprintf '%d\n' "${t1}"
Em bash
isso funciona:
loc(){ local "x=$(exit "$1"):$?"
printf '$%s:\t%d\n' \
x "${x##*:}" \? "$?"
}
Tem a ver com a ordem de avaliação do comando e a atribuição de variáveis. local
possui um valor de retorno próprio - e é o comando em execução no momento, não a substituição do comando. A razão pela qual coisas como ...
x=$(exit 1); echo "$?"
... pode retornar 1 é porque nunca há um retorno nesse comando, exceto para a execução do subshell para atribuir $x
o valor - portanto $?
, não é prejudicado, como acontece em praticamente todos os outros casos em que as substituições de comando são usadas.
De qualquer forma, com local
que se destroçada - mas se você pegá-lo no momento certo - que é, enquanto as expansões ainda estão sendo avaliados e antes de local
's rotinas têm a chance de espancar ele - você ainda pode atribuí-lo.
unset x; loc 130; echo "${x-\$x is unset}"
... imprime ...
$x: 130
$?: 0
$x is unset
No entanto, você deve saber que, em muitos reservatórios, você não pode confiar $?
nesse tipo de avaliação. De fato, isso provavelmente ocorre porque essas conchas não se incomodam em reavaliar a cada momento possível, como talvez bash
- o que eu diria que é provavelmente um comportamento melhor do que bash
o seu. Deseja realmente que o seu intérprete avalie valores de loop recursivamente que provavelmente serão substituídos antes que você tenha a chance de usá-los?
Enfim, é assim que você pode fazer isso.
Dependendo do motivo pelo qual você está tentando obter o código de saída, também é possível executar o if some-command; then echo "Success $?"; else echo "Failure $?"; fi
que não faz nada com a saída do comando, apenas avalia o código de saída da execução do comando. Você pode adicionar or
( or
$ ( around the command and you'll still get the same results. A better example might be
se grep -q 'somestring' somefile; então echo "O código de saída encontrado é $?"; Else "Não encontrou o código de saída é $?"; Fi`.
Você também pode testar o código de retorno de uma função que pode ser um return 3
código de retorno explícito ou implícito, que é o resultado do último comando; nesse caso, você precisa ter cuidado para não ter um echo
no final do , caso contrário, mascara / redefine o código de saída anterior.
command_last () {
echo "True is `true`"
echo "False is `false`"
false
}
command_last; echo $?
# Outputs:
# True is 0
# False is 1
# 1
echo_last () {
echo "True is `true`"
echo "False is `false`"
false
# echo'ing literally anything (or nothing) returns true aka exit 0
echo
}
echo_last; echo $?
# Outputs:
# True is 0
# False is 1
# # Blank line due to empty echo
# 0
Finalmente, um truque sujo, já que você não pode fazer, VAR=(SOME_COMMAND)
porque VAR=()
é uma definição de matriz que você precisa VAR=( $(echo 'Some value') )
.