Qual é a diferença entre a instrução return
e exit
nas funções do Bash em relação aos códigos de saída?
Qual é a diferença entre a instrução return
e exit
nas funções do Bash em relação aos códigos de saída?
Respostas:
A partir man bash
de return [n]
;
Faz com que uma função pare de executar e retorne o valor especificado por n ao seu chamador. Se n for omitido, o status de retorno é o do último comando executado no corpo da função.
... em exit [n]
:
Faça com que o shell saia com o status n. Se n for omitido, o status de saída é o do último comando executado. Uma interceptação em EXIT é executada antes que o shell termine.
EDITAR:
Conforme sua edição da pergunta, em relação aos códigos de saída, return
nada tem a ver com códigos de saída. Os códigos de saída destinam-se a aplicativos / scripts , não a funções. Portanto, a este respeito, a única palavra-chave que define o código de saída do script (aquele que pode ser capturado pelo programa de chamada usando a $?
variável shell) é exit
.
EDIT 2:
Minha última declaração referente exit
está causando alguns comentários. Foi feito para diferenciar return
e exit
para o entendimento do OP e, de fato, em qualquer ponto determinado de um script de programa / shell, exit
é a única maneira de finalizar o script com um código de saída para o processo de chamada.
Cada comando executado no shell produz um local "código de saída": ele define a $?
variável para que o código, e pode ser usado com if
, &&
e outros operadores para condicionalmente executar outros comandos.
Esses códigos de saída (e o valor da $?
variável) são redefinidos a cada execução de comando.
Aliás, o código de saída do último comando executado pelo script é usado como o código de saída do próprio script, conforme visto pelo processo de chamada.
Finalmente, as funções, quando chamadas, agem como comandos do shell em relação aos códigos de saída. O código de saída da função ( dentro da função) é definido usando return
. Portanto, quando uma função return 0
é executada, a execução da função termina, fornecendo um código de saída 0.
func(){ return 50; };func;echo $?
ecoa 50. Portanto, a $?
variável shell não parece estar limitada a exit
.
$?
Expande para o status de saída do pipeline de primeiro plano executado mais recentemente." Essa saída pode ser do shell na forma de uma chamada para exit
(ou chegar ao final do script) ou na forma de uma chamada para return
dentro de uma função.
$?
processo / script atual é limitado exit
ao resultado do último comando executado por este script ou ao resultado. Portanto, se sua última linha de script é a chamada para essa função e essa função retorna 50, sim, a $?
que você produz para o processo que chamou você é 50. No entanto, isso não tem a ver com o return
porque é restrito ao script atual. Só será retornado se essa chamada de função for a última frase do script. exit
, no entanto, sempre termine o script e retorne esse valor $?
ao processo de chamada .
return
não tem nada a ver com códigos de saída". A experiência me diz que não há diferença funcional entre o código de retorno de uma função e o código de saída de um script.
return
fará com que a função atual fique fora do escopo, enquanto exit
fará com que o script termine no ponto em que é chamado. Aqui está um exemplo de programa para ajudar a explicar isso:
#!/bin/bash
retfunc()
{
echo "this is retfunc()"
return 1
}
exitfunc()
{
echo "this is exitfunc()"
exit 1
}
retfunc
echo "We are still here"
exitfunc
echo "We will never see this"
$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()
$?
.
echo fnord | while read x; do exitfunc; done; echo "still here"
imprimirá "ainda aqui". Parece que apenas o while
sub-shell é encerrado neste cenário.
done || exit $?
porém, feia e não exatamente equivalente.
return
fará com que a função atual ou o script de origem fiquem fora do escopo```.
Não acho que alguém tenha realmente respondido totalmente à pergunta porque não descreve como os dois são usados. OK, acho que sabemos que exit mata o script, onde quer que seja chamado e você pode atribuir um status a ele, como sair ou sair 0 ou sair 7 e assim por diante. Isso pode ser usado para determinar como o script foi forçado a parar se chamado por outro script, etc. Chega na saída.
return quando chamado retornará o valor especificado para indicar o comportamento da função, geralmente 1 ou 0. Por exemplo:
#!/bin/bash
isdirectory() {
if [ -d "$1" ]
then
return 0
else
return 1
fi
echo "you will not see anything after the return like this text"
}
verifique assim:
if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi
ou assim:
isdirectory || echo "not a directory"
Neste exemplo, o teste pode ser usado para indicar se o diretório foi encontrado. observe que nada após o retorno não será executado na função. 0 é verdadeiro, mas falso é 1 no shell, diferente de outros programas.
Para obter mais informações sobre funções: http://www.linuxjournal.com/content/return-values-bash-functions
NOTA: A função isdirectory é apenas para fins instrucionais. Não deve ser assim que você executa essa opção em um script real.
test -d $1
para obter o mesmo resultado. Nunca faça if <check> return else return
. <check>
sozinho fará a mesma coisa em todos os idiomas que conheço pelo menos.
isdirectory() { [ -d "$1" ]; }
se comportará exatamente como o que você tem aqui: O valor de retorno padrão de uma função shell, seja atingindo o final de seu código ou por um return
sem argumentos, é o comando mais recente.
return
declaração. É verdade que seu exemplo é simplista e não deve ser usado na produção. Mas é simples, por isso realiza sua tarefa muito bem. Nada de errado com isso.
Lembre-se de que as funções são internas a um script e normalmente retornam de onde foram chamadas usando a instrução return. Chamar um script externo é outra questão inteiramente, e os scripts geralmente terminam com uma instrução de saída.
A diferença "entre a declaração de retorno e saída nas funções BASH em relação aos códigos de saída" é muito pequena. Ambos retornam um status, não valores per se. Um status zero indica sucesso, enquanto qualquer outro status (1 a 255) indica uma falha. A instrução de retorno retornará ao script de onde foi chamada, enquanto a instrução de saída encerrará o script inteiro de onde for encontrado.
return 0 # returns to where the function was called. $? contains 0 (success).
return 1 # returns to where the function was called. $? contains 1 (failure).
exit 0 # exits the script completely. $? contains 0 (success).
exit 1 # exits the script completely. $? contains 1 (failure).
Se sua função simplesmente terminar sem nenhuma instrução de retorno, o status do último comando executado será retornado como o código de status (e será colocado em $?
).
Lembre-se de retornar e sair devolvendo um código de status de 0 a 255, disponível em $?
. Você não pode inserir mais nada em um código de status (por exemplo, retornar "cat"); isso não vai funcionar. Porém, um script pode transmitir 255 motivos diferentes de falha usando códigos de status.
Você pode definir variáveis contidas no script de chamada ou fazer eco dos resultados na função e usar a substituição de comandos no script de chamada; mas o objetivo do retorno e da saída é passar códigos de status, não valores ou resultados de computação, como seria de esperar em uma linguagem de programação como C.
Às vezes, você executa um script usando .
ou source
.
. a.sh
Se você incluir um exit
no a.sh
, ele não apenas encerrará o script, mas também encerrará sua sessão do shell.
Se você incluir um return
no a.sh
, ele simplesmente interromperá o processamento do script.
return: can only 'return' from a function or sourced script
, o que o torna inadequado para um script geral.
all
situações. Usar .
ou source
executar o script no shell atual, em vez de gerar um sub shell. O script precisa saber como deve ser usado. Ai do usuário que faz o contrário. Pessoalmente, recomendo a leitura de scripts antes de executá-los pela primeira vez.
trap
função ERR EXIT
e, em seguida, primeiro salvar o código de saída de um comando com falha errCode=$?
e sair do script (de origem ou não) com o local return $errCode || exit $errCode
onde os ||
meios "se eu não puder retornar porque não foi de origem" , basta sair ".
Em palavras simples (principalmente para iniciantes em codificação), podemos dizer,
`return` : exits the function,
`exit()` : exits the program(called as process while running)
Além disso, se você observou, isso é muito básico, mas ...,
`return` : is the keyword
`exit()` : is the function
exit
não é mais ou menos uma função do que return
. Eles são comandos internos. Nem são palavras reservadas.
exit
encerrar o processo atual ; com ou sem código de saída, considere isso um sistema mais que uma função do programa. Observe que, ao fazer o sourcing, exit
o shell será finalizado; no entanto, ao executar, será apenas exit
o script.
return
de uma função, volte para a instrução após a chamada, com ou sem um código de retorno. return
é opcional e está implícito no final da função. return
só pode ser usado dentro de uma função.
Quero acrescentar que, enquanto estiver sendo originado, não é fácil para exit
o script de dentro de uma função sem matar o shell. Eu acho que um exemplo é melhor em um script de 'teste'
#!/bin/bash
function die(){
echo ${1:=Something terrible wrong happen}
#... clean your trash
exit 1
}
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
fazendo o seguinte:
user$ ./test
Whatever is not available
user$
test
- e - a concha será fechada.
user$ . ./test
Whatever is not available
somente test
terminará e o prompt será exibido.
A solução é incluir o potencial procedimento em (
e)
#!/bin/bash
function die(){
echo $(1:=Something terrible wrong happen)
#... clean your trash
exit 1
}
( # added
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
) # added
agora, em ambos os casos, apenas test
sairá.
(
e )
colocar esse bloco em um sub shell, efetivamente desabilitando o .
comando (origem) como se você tivesse executado o script de teste normalmente, que está em um sub shell. IO script não é executado com .
ou source
então você possui efetivamente 2 sub-shells.
A pergunta do OP: Qual é a diferença entre a declaração de retorno e saída nas funções BASH em relação aos códigos de saída?
Por fim, alguns esclarecimentos são necessários:
Na lista de marcadores acima, escolha entre "(x | y)" sempre o primeiro item ou sempre o segundo item para obter instruções sobre funções e retorno ou shells e saída, respectivamente.
O que está claro é que ambos compartilham o uso comum da variável especial $? para passar valores para cima depois que eles terminam.
* Agora, para as formas especiais que $? Pode ser configurado:
Vale a pena notar que $? pode ser atribuído um valor chamando exit em um sub shell, assim:
# (exit 259)
# echo $?
3
exit 259
ecoam como se 3
o valor final de saída fosse um único byte. 259 % 256 = 3
Primeiro de tudo, return
é uma palavra-chave e exit
meu amigo é uma função.
Dito isto, aqui está uma das explicações mais simples.
return
Retorna um valor de uma função.
exit
Ele sai ou abandona o shell atual.
return
é uma palavra-chave. O retorno é muito mais do que apenas códigos de saída, e é por isso que a comparação não é justa.
exit
nem return
são "palavras-chave", ou, como os festança chamadas manuais eles "palavras reservadas". Também não é uma "função", no sentido de uma função bash. Ambos são comandos internos, no idioma do bash. (Não é uma função C biblioteca padrão chamado exit()
, e a linguagem de programação C tem uma palavra reservada return
, mas aqueles que não deve ser confundido com os comandos bash, apesar de sua semântica são curiosamente similar.)
help <command>
seu shell para obter informações sobre o que um shell incorporado fará. No seu casohelp return
ehelp exit