Funções aninhadas
Você também pode chamar uma função dentro de outra função. Neste caso, a ordem em que as funções foram declaradas não é importante.
Ou seja, você pode invocar uma função que ainda não foi declarada.
Porém, por questão de organização e manutenção de código, declare sempre suas funções no início do script.
Arquivos de função
Se o seu script começar a ficar muito grande e complexo, é uma boa prática criar um arquivo (ou mais), só pra armazenar as funções.
Então, no script, simplesmente carregue esse arquivo (como o
include,
import,
use, etc - de outras linguagens).
Para carregar as funções de um arquivo, caso este esteja no mesmo diretório do script, use
source:
source arquivo_de_funcoes
Desdeclarando funções
Nem sei se a palavra "desdeclarar" existe, mas foi o que imaginei de
Undeclaring functions.
Isso é feito através do comando
unset:
unset listar
Se tentarmos o comando 'listar', teremos mensagem de erro, pois o shell já a 'liberou' de sua 'memória'.
Passando argumentos para as funções
Como, depois de declaradas, podemos usar as funções assim como usamos os comandos, também podemos passar argumentos para funções, assim como fazemos com os comandos.
Os argumentos são armazenados da mesma forma que os parâmetros, quando usamos comandos. Ou seja, o nome do script é armazenado na variável '$0', o 1º argumento fica na variável '$1', o 2º na '$2', ... O número total de argumentos na '$#' e todos são armazenados na '$@'.
Vamos testar criando o script "args.sh":
#!/bin/sh
args()
{
echo "Nome: $0"
echo "Total: $#"
echo "Primeiro: $1"
echo "Segundo: $2"
echo "Terceiro: $3"
echo
echo "Todos: $@"
echo
}
args arg1 arg2 arg3
Permita e execute:
chmod +x args.sh
$ ./args.sh
Códigos de retorno (return codes)
Como vimos, todo e qualquer comando do
Unix retorna algum código. '0' caso tenha dado tudo certo e outro número para mostrar que houve um erro, onde números diferentes são usados para indicar erros diferentes.
O
bash armazena o código de retorno do último comando na variável '$?'.
Por exemplo, digite no terminal:
comando_inexistente
$ echo $?
Que exibirá o erro, pro caso do comando não existir.
Agora, teste um comando que funcione bem:
ls
$ echo $?
Return
Como estes códigos de saída são amplamente usados no *Unix, é uma boa prática fazer o mesmo em seus scripts. Usa-se o comando
return [|inteiro], ao invés de
exit [|inteiro] nas funções de seu script, pois queremos somente que a função termine, não o script, e retornando um inteiro para o script, fazendo uma comunicação deste com a função.
Se não usarmos um
return em uma função, o '$?' armazenará o código de retorno do último comando da função.
Podemos escrever só 'return' sem retornarmos explicitamente um número. Quando a função encontra 'return' ela termina imediatamente (não executa o que vem em seguida) e '$?' armazenará o código de retorno do último comando antes de encontrar da função chegar em 'return'.
Ou retornamos algo específico de nosso propósito. Dentro de condicionais, por exemplo:
if(tudo certo)
return 2112
else
return 666
Variáveis globais
* Aqui vai uma pequena e importante ressalva, para você que já vem de outra linguagem de programação:
Por padrão, as variáveis em Shell são globais. Se desejar ter uma variável local em suas funções, as declare como 'local'. Exemplo:
local VAR='Existem variáveis locais!
Sem isso, as variáveis que você cria dentro das função estarão disponíveis por todo o script, ou caso já existam serão sobrescritas. Portanto, cuidado, dê nomes únicos para as suas variáveis ou adicione o
local na frente.