Criando funções em scripts bash (Linux/Bash)
Overview
Se você já se encontrou duplicando código em seus scripts bash e se perguntando se haveria uma maneira melhor de fazer as coisas, esta postagem é para você. Aqui, compartilho uma luz sobre como criar, chamar e manipular funções em bash, tornando seus scripts mais limpos e reutilizáveis. Então, pegue sua xícara de café favorita e vamos mergulhar juntos nas maravilhas das funções bash!
Enquanto escrevia um script particularmente grande, percebi que precisaria repetir/reutilizar partes do código e duplicar código é algo que me irrita profundamente. Então pesquisei sobre funções em scripts bash e fiquei semi-feliz com o resultado da pesquisa. Neste post, vou compartilhar o básico sobre como criar e utilizar funções nos scripts bash.
Antes que você saia correndo para refatorar todos aqueles bash scripts que você tem, vale uma nota importante: Diferente das outras linguagens, os bash scripts não permitem retornar valores. Você pode retornar um valor numérico indicando sucesso (sucesso = zero) ou falha (qualquer outro numero).
Caso você tente retornar uma string, vai ser agraciado pela seguinte mensagem:
return: string return: numeric argument required
Calma, não precisa desanimar. Existem formas de conseguir retornar valores após a execução de uma função, mas vou deixar para explicar isso mais para frente. Agora vamos à sintaxe de como criar e chamar as funções:
Declaração de funções
Abaixo estão algumas formas de declarar uma função em um script bash:
Forma 1
nome_da_funcao() {
# <codigo>
}
Forma 2
function nome_da_funcao() {
# <codigo>
}
Forma 3
function nome_da_funcao {
# <codigo>
}
Todas as 3 formas tem o mesmo efeito. Não sei se existe alguma diferença ou incompatibilidade séria entre elas. Acredito que não, pois não vi nenhum alerta nas pesquisas que realizei, mas se descobrir, atualizo o post. 🙂
Para chamar as funções que você criou é simples, basta incluir o nome da função, da mesma forma que você faria com funções nativas do Linux.
Veja este exemplo:
#!/bin/bash
function hello_world {
echo "Hello World!"
}
hello_world
No exemplo acima, declaramos a função “hello_world” e depois ela é chamada na última linha do script. O resultado vai ser a frase “Hello World!” vai ser escrita no terminal.
Passando argumentos para as funções
Uma parte importante da motivação para criar funções é que ela possa receber argumentos. Esta parte do procedimento é simples e é exatamente igual a passar argumentos para um script. Sendo assim, você pode utilizar a mesma lógica apresentada no post “Recuperando argumentos passados para um script shell” para recuperar os argumentos passados para a função.
A diferença é que, mesmo dentro da função, se você tentar utilizar a variável $0 ($ zero), ela vai possuir o nome do script e não da função.
Veja o exemplo:
#!/bin/bash
function hello_world {
echo "Hello World!"
echo "Zero: $0"
echo "First: $1"
for arg in "$@"
do
i=$((i+1))
echo "Arg $i: $arg"
done
}
hello_world foo bar "bacon foo" "bacon bar"
No código acima, adaptei a função “hello_world” para que ela mostre no terminal todos os argumentos que foram passados para ela.
Na última linha do código, eu passo os argumentos: foo, bar, “bacon foo” e “bacon bar” para a função.
O resultado desta função ficaria assim:
Hello World!
Zero: ./t.sh
First: foo
Arg 1: foo
Arg 2: bar
Arg 3: bacon foo
Arg 4: bacon bar
Este exemplo mostra como os argumentos são processados.
Retornando valores
Ok, as funções em si não retornam valores, mas você consegue utilizar variáveis para transferir e verificar estes valores.
A forma mais simples é utilizar uma variável global para armazenar o valor.
#!/bin/bash
function func1 {
resultado="deu certo"
}
func1
echo "$resultado"
Existe uma alternativa para as variáveis globais… o que é bom, pois algumas pessoas não gostam muito de utilizar estas variáveis. A alternativa é utilizar substituição:
#!/bin/bash
func2() {
local resultado_interno="deu certo!"
echo "$resultado_interno"
}
resultado=$(func2)
echo "$resultado"
Se não estiver satisfeito, também existe uma terceira opção, mas acho utiliza-la fica meio confuso na hora de ler o script. A terceira forma é escrever sua função de modo que ela aceite uma variável como argumento, que servirá para armazenar o resultado. Exemplo:
#!/bin/bash
function func3() {
local __resultado=$1
local result="deu certo!!"
eval $__resultado="'$result'"
}
func3 resultado
echo "$resultado"
Da para perceber que fica um pouco mais confuso, mas funciona bem… apesar de depender da função eval.
Ela é uma função onde você constrói um comando através da concatenação de uma série de argumentos, mas isso é um assunto para um possível post futuro.
Bom, neste post mostrei como declarar e chamar um função, como passar e ler os argumentos para ela e como retornar o resultado. Divirta-se otimizando seus scripts bash! 🙂
Espero ter ajudado!