Estou trabalhando com um script bash e quero executar uma função para imprimir um valor de retorno:
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Quando executo fun2
, ele não imprime "34". Por que esse é o caso?
bash
function
return-value
mindia
fonte
fonte
return
no seu caso, é essencialmente o mesmoexit code
que o intervalo0 - 255
. Useecho
como sugerido por @septi. Os códigos de saída podem ser capturados com$?
.function a() { echo 34; }
function b() { while read data; do echo $data ; done ;}
a | b
Respostas:
Embora o bash tenha uma
return
instrução, a única coisa que você pode especificar com ela é o próprioexit
status da função (um valor entre0
e255
, 0 significando "sucesso"). Entãoreturn
não é o que você quer.Você pode converter sua
return
instrução em umaecho
instrução - dessa forma, a saída da sua função pode ser capturada usando$()
chaves, o que parece ser exatamente o que você deseja.Aqui está um exemplo:
Outra maneira de obter o valor de retorno (se você deseja apenas retornar um número inteiro de 0 a 255) é
$?
.Além disso, observe que você pode usar o valor de retorno para usar a lógica booleana, como
fun1 || fun2
só será executadafun2
sefun1
retornar um0
valor. O valor de retorno padrão é o valor de saída da última instrução executada na função.fonte
fun1
e, em seguida, o valor de retorno é armazenado$?
. Embora eu não recomendo fazer isso ...$?
?||
construção, um código de saída 0 é considerado sucesso e, portanto, "verdadeiro". Diferente de zero é erro e, portanto, falso. Pensefun1 || fun2
como atalho para "se fun1 retorna sucesso ou fun2 retorna sucesso" em vez de um operador nos próprios valores de retorno reais.$(...)
captura o texto enviado ao stdout pelo comando contido nele.return
não gera saída para stdout.$?
contém o código do resultado do último comando.fonte
return
é usado para definir$?
qual é oexit status
. No exemplo acima,fun1
'sexit status
seria34
. Além disso, observe que$(...)
também captura stderr além de stdout do comando especificado.Funções no Bash não são funções como em outro idioma; na verdade são comandos. Portanto, as funções são usadas como se fossem binários ou scripts buscados no seu caminho. Da perspectiva da lógica do seu programa, não deve haver realmente nenhuma diferença.
Os comandos do shell são conectados por pipes (também conhecidos como fluxos), e não por tipos de dados fundamentais ou definidos pelo usuário, como em linguagens de programação "reais". Não existe um valor de retorno para um comando, talvez principalmente porque não há uma maneira real de declará-lo. Pode ocorrer na página do manual ou na
--help
saída do comando, mas ambos são legíveis apenas por humanos e, portanto, são gravados ao vento.Quando um comando deseja obter entrada, ele o lê em seu fluxo de entrada ou na lista de argumentos. Nos dois casos, as cadeias de texto devem ser analisadas.
Quando um comando deseja retornar algo, ele deve retornar
echo
ao fluxo de saída. Outra maneira frequentemente praticada é armazenar o valor de retorno em variáveis globais dedicadas. A gravação no fluxo de saída é mais clara e flexível, porque também pode levar dados binários. Por exemplo, você pode retornar um BLOB facilmente:Como outros escreveram neste segmento, o chamador também pode usar a substituição de comando
$()
para capturar a saída.Paralelamente, a função "retornaria" o código de saída de
gpg
(GnuPG). Pense no código de saída como um bônus que outros idiomas não possuem ou, dependendo do seu temperamento, como um "Schmutzeffekt" das funções do shell. Esse status é, por convenção, 0 em caso de sucesso ou um número inteiro no intervalo de 1 a 255 para outra coisa. Para deixar isso claro:return
(comoexit
) pode assumir apenas um valor de 0 a 255, e valores diferentes de 0 não são necessariamente erros, como geralmente é afirmado.Quando você não fornece um valor explícito,
return
o status é obtido do último comando em uma instrução / função / comando do Bash e assim por diante. Portanto, sempre há um status ereturn
é apenas uma maneira fácil de fornecê-lo.fonte
A
return
instrução define o código de saída da função, da mesma formaexit
que fará para todo o script.O código de saída para o último comando está sempre disponível na
$?
variávelfonte
O problema com outras respostas é que eles usam um global, que pode ser sobrescrito quando várias funções estão em uma cadeia de chamadas ou
echo
significa que sua função não pode gerar informações de diagnóstico (você esquecerá que sua função faz isso e o "resultado", ou seja, retorna valor, conterá mais informações do que o chamador espera, levando a erros estranhos) oueval
muito pesados e invasivos.A maneira correta de fazer isso é colocar as coisas de nível superior em uma função e usar uma
local
regra de escopo dinâmico do bash. Exemplo:Isso gera
O escopo dinâmico significa que
ret_val
aponta para um objeto diferente, dependendo do chamador! Isso é diferente do escopo lexical, que é o que a maioria das linguagens de programação usa. Este é realmente um recurso documentado , fácil de perder, e não muito bem explicado, eis a documentação para ele (a ênfase é minha):Para alguém com experiência em C / C ++ / Python / Java / C # / javascript, este é provavelmente o maior obstáculo: as funções no bash não são funções, são comandos e se comportam como tal: podem gerar saída para
stdout
/stderr
, podem canalizar / out, eles podem retornar um código de saída. Basicamente, não há diferença entre definir um comando em um script e criar um executável que possa ser chamado a partir da linha de comando.Então, em vez de escrever seu script assim:
escreva assim:
onde
main()
declararet_val
comolocal
e todas as outras funções retornam valores viaret_val
.Veja também a seguinte pergunta sobre Unix e Linux: Escopo de variáveis locais nas funções do shell .
Outra solução, talvez ainda melhor, dependendo da situação, é a postada pelo ya.teck que utiliza
local -n
.fonte
Outra maneira de obter isso é as referências de nome (requer o Bash 4.3+).
fonte
-n <name>=<reference>
faz: torna a variável recém-criada uma referência a outra apontada por<reference>
. Atribuições adicionais<name>
são executadas na variável referenciada.Eu gosto de fazer o seguinte se estiver executando em um script em que a função está definida:
Eu gosto disso, pois, em seguida, posso incluir instruções de eco em minhas funções, se eu quiser
fonte
Como um complemento para as excelentes postagens de outras pessoas, aqui está um artigo que resume essas técnicas:
Retornando valores das funções Bash
fonte
Git Bash no Windows usando matrizes para vários valores de retorno
CÓDIGO BASH:
SAÍDA ESPERADA:
fonte