Digamos que tenho uma função bash como esta:
gmx(){ echo "foo"; }
esta função funcionará implicitamente retornar o valor de saída do comando echo
, ou usar return é necessário?
gmx(){ echo "foo"; return $? }
Presumo que o caminho bash funciona, o status de saída do comando final da função bash é aquele que obtém “retornado”, mas não é 100% certo.
Resposta
return
faz um retorno explícito de uma função shell ou” script de ponto “(um script originado). Se return
não for executado, um retorno implícito é feito no final da função shell ou script de ponto.
Se return
é executado sem um parâmetro, é equivalente a retornar o status de saída do comando executado mais recentemente.
É assim que return
funciona em todos os POSIX shells.
Por exemplo,
gmx () { echo "foo" return "$?" }
é, portanto, equivalente a
gmx () { echo "foo" return }
que é o mesmo que
gmx () { echo "foo" }
Em geral, raramente é necessário usar $?
em tudo. Na verdade, ele só é necessário se você precisar salvá-lo para uso futuro, por exemplo, se precisar investigar seu valor várias vezes (nesse caso, você atribuiria seu valor a uma variável e executaria uma série de testes nessa variável). / p>
Comentários
Resposta
Da página do manual bash(1)
:
Quando executado, o status de saída de uma função é o status de saída do último comando executado no corpo.
Comentários
- certo, e um corolário pode ser que a instrução de retorno nada mais é do que o status de saída?
- Acho que
return
é um comando embutido – emborareturn 1
seja diferente deexit 1
, etc, então - ” return [n]: Faz com que uma função pare de ser executada e retorna o valor especificado por n para seu chamador. Se n for omitido, o status de retorno será o do último comando executado no corpo da função. ” (ibid) Portanto,
return
força o status de saída de uma função para um valor específico, se especificado. - @AlexandwrMills Sim,
return
eexit
são ambos integrados, excetoreturn
que só pode ser usado dentro da função. Você pode ‘ t encerrar um script comreturn
. O status de saída é o valor que o comando retorna.return
é o comando que retorna esse valor. Portanto, a ” instrução de retorno nada mais é do que o status de saída ” não é muito precisa. Um é um valor, o outro é comando mais valor. - @AlexanderMills,
return
retorna da função,exit
sai de todo o shell. É ‘ exatamente o mesmo que em, digamos C comreturn
vs.exit(n)
, oureturn
vs.sys.exit()
em Python.
Resposta
Vou apenas adicionar algumas notas de cautela às respostas já fornecidas:
-
Embora
return
tenha um significado muito especial para o shell, do ponto de vista da sintaxe, é um comando interno do shell e uma instrução de retorno é analisado como qualquer outro comando simples. Então, isso significa que, como no argumento de qualquer outro comando,$?
quando não cotado, estaria sujeito a divisão + globPortanto, você precisa citar que
$?
para evitá-lo:return "$?"
-
return
geralmente não aceita nenhuma opção (ksh93
“s aceita o usual--help
,--man
,--author
… embora). O único argumento esperado (opcional) é o código de retorno. O intervalo de códigos de retorno aceitos varia de shell para shell, e se algum valor fora de 0..255 é refletido corretamente em
também varia de shell para shell. Veja Código de saída padrão quando o processo é encerrado? para obter detalhes sobre isso.
A maioria dos shells aceita números negativos (afinal, o argumento passado para a _exit()
/ exitgroup()
chamada do sistema é uma int
, portanto, com valores abrangendo pelo menos – 2 31 a 2 31 -1, então só faz sentido que os shells aceitem o mesmo intervalo para suas funções).
A maioria dos shells usa o waitpid()
e co. API para recuperar esse status de saída, no entanto, nesse caso, é truncado para um número entre 0 e 255 quando armazenado em $?
. Mesmo chamando uma função não envolve a geração de um processo e usado waitpid()
para recuperar seu status de saída, pois tudo é feito no mesmo processo, muitos shells também imitam que waitpid()
comportamento ao invocar funções. O que significa que mesmo se você chamar return
com um valor negativo, $?
conterá um número positivo.
Agora, entre aqueles shells cujo return
aceita números negativos (ksh88, ksh93, bash, zsh, pdksh e derivados diferentes de mksh, yash), existem alguns ( pdksh e yash) que precisam ser escritos como return -- -123
, caso contrário -123
é considerado três -1
, -2
, -3
opções inválidas.
Como pdksh e seu de rivatives (como OpenBSD sh
ou posh
) preservam o número negativo em $?
, isso significa que fazer return "$?"
iria falhar quando $?
contiver um número negativo (o que aconteceria quando o último comando executado fosse uma função que retornasse um número negativo ).
Portanto, return -- "$?"
seria melhor nesses shells. No entanto, observe que embora seja compatível com a maioria dos shells, essa sintaxe não é POSIX e, na prática, não é compatível com mksh
e derivados de ash.
Então, para resumir, com Shells baseados em pdksh, você pode usar números negativos em argumentos para funções, mas se o fizer, return "$@"
não funcionará. Em outros shells, return "$@"
funcionará e você deve evitar usar números negativos (ou números fora de 0..255) como argumentos para return
.
Em todos os shells que eu conheço, chamar return
de dentro de um subshell em execução dentro de uma função fará com que o subshell saia (com o status de saída fornecido, se houver, ou aquele do último comando executado), mas não causará um retorno da função (para mim, não está claro se POSIX oferece essa garantia, alguns argumentam que exit
deve ser usado em vez de subshells de saída funções internas). Por exemplo
f() { (return 3) echo "still inside f. Exit status: $?" } f echo "f exit status: $?"
produzirá:
still inside f. Exit status: 3 f exit status: 0
Resposta
Sim, o valor de retorno implícito de uma função é o status de saída do último executado comando . Isso também é verdade em qualquer ponto de qualquer script de shell. Em qualquer ponto da sequência de execução do script, o status de saída atual é o status de saída do último comando executado. Mesmo comando executado como parte de uma atribuição de variável: var=$(exit 34)
. A diferença com as funções é que uma função pode alterar o status de saída no final da execução da função.
A maneira alternativa de alterar o “status de saída atual” é iniciar um sub shell e encerrá-lo com qualquer status de saída necessário:
$ $(exit 34) $ echo "$?" 34
E sim, o status de saída expansão precisam ser citados:
$ IFS="123" $ $(exit 34) $ echo $? 4
Um (exit 34)
também funciona.
Alguns podem argumentar que uma construção mais robusta deve ser $(return 34)
, e que uma saída deve “sair” do script que está sendo executado. Mas $(return 34)
não funciona com qualquer versão do bash. Portanto, não é portátil.
A maneira mais segura de definir um status de saída é usá-lo como foi projetado para funcionar, definir e return
a partir de uma função :
exitstatus(){ return "${1:-"$?"}"; }
Então, no final de uma função. é exatamente equivalente a nada ou return
ou return "$?"
. O final de uma função não precisa significar a “última linha de código de uma função”.
#!/bin/sh exitstatus(){ a="${1:-"$?"}"; return "$a"; } gmx(){ if [ "$1" = "one" ]; then printf "foo "; exitstatus 78 return "$?" elif [ "$1" = "two" ]; then printf "baz "; exitstatus 89 return else printf "baz "; exitstatus 90 fi }
Irá imprimir:
$ ./script foo 78 baz 89 baz 90
O único uso prático para "$?"
é imprimir seu valor: echo "$?"
ou armazenar em uma variável (pois é um valor efêmero e muda a cada comando executado): exitstatus=$?
(lembre-se de citar a variável em comandos como export EXITSTATUS="$?"
.
No comando return
, o intervalo válido de valores é geralmente de 0 a 255, mas entenda que os valores de 126 + n
são usados por alguns shells para sinalizar o status de saída especial, portanto, a recomendação geral é usar 0-125.
return
é que para funções definidas comof() (...; cmd; return)
, evita a otimização que alguns shells fazem ao executar ocmd
no mesmo processo do subshell. Com muitos shells, isso também significa que o status de saída da função não ‘ carrega a informação de quecmd
foi eliminado quando (a maioria dos shells pode ‘ recuperar essas informações de qualquer maneira).sh
ouposh
), você ‘ d precisariareturn -- "$?"
se houvesse um chance de que o último comando foi uma função que retornou um número negativo.mksh
(também baseado em pdksh) proíbe funções de retornarem valores negativos.return x
funciona de maneira diferente deexit x
… a única coisa que sei é quereturn x
não sairá do processo atual.return
é usado para retornar de uma função ou um script de ponto.exit
faz algo completamente diferente (encerra um processo).