- Gerar link
- X
- Outros aplicativos
Postagem em destaque
- Gerar link
- X
- Outros aplicativos
Visão geral
Como em outras linguagens de programação, o Bash tem sua funções, embora sua aplicação seja limitada. Uma função é uma sub-rotina, um bloco de código que implementa um conjunto de operações. Um 'nome' que executa uma tarefa especificada. Sempre que há código repetitivo, quando uma tarefa se repete com apenas pequenas variações no procedimento, é recomendado usar uma função.Sintaxe
function NomeDaFuncao() |
ou | NomeDaFuncao() |
A definição da função deve preceder a primeira chamada da mesma. Não existe um método para declarar a função como ocorre em outras linguagens. Funções são chamadas, simplesmente invocando seus nomes sem o uso de parênteses. Uma chamada é equivalente a um comando. Mantenha sempre a boa prática de instanciar suas funções no inicio do Script para melhor organização do código ou até mesmo garantir que a chamada da função esteja posterior a sua instância. A expressão 'function' que precede o nome da função é opcional, mas tenha a boa prática de usá-lo para melhor identificar sua função.
Criando uma função
Você deve escolher um nome que melhor define sua função, com o qual você seja capaz de identificar o seu procedimento e o que faz. Não faz sentido criar uma função chamada 'Contar_Numeros', se ela tem como finalidade criar arquivos. Acredite um 'bom nome' faz toda diferença.Criando nossa primeira função chamada 'Mensagem'.
function Mensagem()
{
# Imprimindo mensagem na tela.
echo 'Isso é uma função.'
echo 'FIM'
}
Chamando a função.
$ Mensagem
Isso é uma função.
Função chamada 'NumeroPar', que lista somente os números pares de 0 à 10.
NumeroPar()
{
for NUM in $(seq 0 2 10)
do
echo "Número $NUM"
done
}
Chamando a função
$ NumeroPar
Número 0
Número 2
Número 4
Número 6
Número 8
Número 10
Funções compactas
Podemos criar funções compactadas, instanciando-as em uma única linha de comando; separando as instruções utilizando o carácter ';' ponto e vírgula. Apesar de funcionar, não é recomendado em casos onde há funções com muitas linhas de instruções; isso dificultaria a compressão do código e até uma manutenção posterior.Uma função no modo compacto.
function Aviso(){ echo 'É uma função compacta.'; echo 'FIM'; }
Código de retorno
Os códigos de retorno são importantes para definir o status de execução de uma determinada tarefa. Identifica se um procedimento teve êxito ou se ocorreram erros durante a execução.Capturar código:
Variável | Descrição |
---|---|
$? | Armazena o código de retorno do último comando executado. |
Códigos de retorno:
Código | Descrição |
---|---|
0 | Sucesso |
1 | Falha |
Para criar uma função e definir seus códigos de retorno, precisamos utilizar o comando 'return'.
Sintaxe
return N
O comando return faz com que uma função ou script-fonte finalize com o valor de retorno especificado em N. Se N for omitido, o status de retorno é do último comando executado dentro da função ou script.
Criando uma função chamada 'texto' que lê uma mensagem digitada pelo usuário.
texto()
{
# Informativo
echo 'Digite sua mensagem'
# Lê a mensagem digitada.
read MSG
# Se 'MSG' for nula, finaliza a função com o código de retorno 1 (FALHA),
# caso contrário retorna 0 (SUCESSO)
[ -z $MSG ] && return 1 || return 0
}
Para exibir o código de retorno, vou utilizar a linha de comando 'echo $?' após a chamada da função.
$ texto; echo $?
Digite sua mensagem
Aprendendo Shell Script.
0
Executando a função sem inserir os dados.
$ texto; echo $?
Digite sua mensagem
1
Também podemos tratar diretamente o código de retorno, testando o valor armazenado na variável '$?'.
Criei uma função chamada 'Validar_Usuario' que verifica se o usuário informado existe no sistema; retornando uma mensagem e o código de status.
Validar_Usuario()
{
# Lê os dados e armazena em 'USUARIO'
read -p 'Informe o nome do usuário: ' USUARIO
# Executa o comando sem imprimir nada na tela.
id $USUARIO &>/dev/null
# Verifica o código de retorno do comando 'id'
if [ $? -eq 0 ]; then
# Se o usuário existir, imprime uma mensagem contendo o nome do usuário
echo "$USUARIO: usuário existe."
# Finaliza a função com status 0
return 0
fi
# Mensagem padrão
# Se a condição anterior foi satisfeita, o script jamais chegará aqui.
echo "$USUARIO: usuário desconhecido."
# Se chegou até aqui, finaliza a função com status 1
return 1
}
Chamando a função.
$ Validar_Usuario ; echo $?
Informe o nome do usuário: juliano
juliano: usuário existe.
0
Testando com um usuário inválido.
$ Validar_Usuario ; echo $?
Informe o nome do usuário: francisco
francisco: usuário inválido.
1
Argumentos
O Shell trata a função como se fosse um comando e a forma de se passar os argumentos não é diferente. Realizando a chamada da função seguida dos argumentos. Esse recurso é bem útil quando precisamos mudar o comportamento de uma função passando parâmetros específicos para processamento.
Sintaxe
funcao arg1 arg2 argN ...O recebimento dos argumentos são definidos por parâmetros posicionais, ou seja, determina a posição de um argumento na função.
Exemplo
$1 - O primeiro argumento da função$2 - Segundo argumento da função
$8 - Oitavo argumento da função
....
Parâmetros posicionais:
$1..$9 |
${10}...${NN} |
Função que imprime os parâmetros posicionais.
imprimir_args()
{
echo "Parâmetros posicionais."
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
}
Passando os parâmetros com a função.
$ imprimir_args Debian Slackware CentOS
Parâmetros posicionais.
$1 = Debian
$2 = Slackware
$3 = CentOS
Criando uma função chamada 'info_grupo' que retorna informações sobre os grupos do usuário e que a passagem do argumento é obrigatória.
info_grupo()
{
# Verifica se o primeiro argumento foi omitido.
if [ -z "$1" ]; then
echo "Requer nome do usuário."
# Um código de status indicando que ocorreu um erro
# na passagem de argumento.
return 3
fi
# Obtem informações do usuário armazenado em '$1'
id $1
# Retorna o código de status do comando 'id'
return $?
}
Chamado a função de 3 formas diferentes e capturando o código de status.
Com usuário válido.
$ info_grupo juliano; echo $?
uid=1000(juliano) gid=1000(juliano) grupos=1000(juliano),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
0
Com usuário inválido.
$ info_grupo francisco; echo $?
id: “francisco”: no such user
1
Sem argumento.
$ info_grupo; echo $?
Requer nome do usuário.
3
Além de tratar a passagem de argumento, a função possui 3 códigos de status. SUCESSO, FALHA e ERRO DE PARÂMETRO.
Nos exemplos anteriores capturamos os argumentos referenciando sua posição na função. Mas e quando a função possuir um número indeterminado de argumentos ? O que fazer para capturar todos eles ?
Para essa finalidade utilizamos a variável '$*', que lista todos os parâmetros em uma expressão.
Criei a função 'listar_args' que imprime todos os parâmetros posicionais e argumentos passados na função.
listar_args()
{
# Parâmetro posicional.
# ** Não é importante, apenas para demonstração ***
i=1
# Lista todos os argumentos da função
for arg in $*
do
# Imprime o parâmetro posicional e o rgumento armazenado em 'arg'
echo "\$$((i++)) = ${arg}"
done
}
Chamando a função e passando seus argumentos.
$ listar_args Debian Slackware CentOS Ubuntu Fedora Arch Manjaro Suse
$1 = Debian
$2 = Slackware
$3 = CentOS
$4 = Ubuntu
$5 = Fedora
$6 = Arch
$7 = Manjaro
$8 = Suse
Argumentos compostos.
Um argumento composto é expressão que contém espaços entre elas e que precisa ser processada como um único argumento. Para isso precisamos passar o argumento entre aspas duplas (") ou simples ('), porém isso não seria suficiente; pois o laço iria interpretar como elementos separados.Para demonstrar o que estou dizendo, vou chamar a função 'listar_args' passando um argumento composto.
$ listar_args "Linux Debian" Slackware
$1 = Linux
$2 = Debian
$3 = Slackware
Talvez você esteja pensando.
-E se colocar a variável $* entre aspas, desse jeito "$*" ? Não resolveria o problema ?
Posso dizer que pioraria ainda mais, mas vamos ver o resultado.
listar_args()
{
# Parâmetro posicional.
# ** Não é importante, apenas para demonstração ***
i=1
# MODIFICADO PARA "$*"
for arg in "$*"
do
# Imprime o parâmetro posicional e o rgumento armazenado em 'arg'
echo "\$$((i++)) = ${arg}"
done
}
Chamando a função com os mesmos argumentos.
$ listar_args "Linux Debian" Slackware
$1 = Linux Debian Slackware
A maneira de resolver esse problema é utilizar a variável "$@" (entre aspas). Dessa forma os elementos são listados como strings separadas e os elementos entre aspas são interpretados com um único argumento.
listar_args()
{
# Parâmetro posicional.
# ** Não é importante, apenas para demonstração ***
i=1
# MODIFICADO PARA "$@"
for arg in "$@"
do
# Imprime o parâmetro posicional e o rgumento armazenado em 'arg'
echo "\$$((i++)) = ${arg}"
done
}
Chamando a função.
$ listar_args "Linux Debian" Slackware
$1 = Linux Debian
$2 = Slackware
Muita atenção no momento que for usar as variáveis ($* e $@) para não perder horas procurando onde está o problema da sua função ou script no momento em que lê os argumentos passados.
Relembrando
Variável | Descrição |
---|---|
$* | Lê todos os argumentos como uma expressão única. (junto) |
$@ | Lê todos os argumentos como strings protegidas. (separadas e composta) |
Considerações finais
É possível criar um função dentro de outra.Exemplo
Funcao1()
{
# Bloco de instruções da primeira função
echo Debian
Funcao2()
{
# Bloco de instruções da segunda função
echo Slackware
}
}
Dessa maneira somente a função 'Funcao1' ficará visível e poderá ser chamada. Enquanto a 'Funcao2' só ficará disponível quando a 'Funcao1' for executada; ou seja, a função só será instanciada quando a função que a antecede for chamada e assim por diante.
Uma função não pode conter somente linhas comentadas ou está vazia.
Exemplo
MinhaFuncao()
{
# Só tem comentário aqui.
# Quem sou eu ? Para onde vou ?
}
ou
MinhaFuncao()
{
}
Não é possível instanciar uma função em conexões PIPE.
Exemplo
df -h | Capacidade(){ echo $*; }
Bom pessoal essa foi uma pequena abordagem de como criar funções e tratar seus argumentos. Como sempre, espero que seja útil para vocês. Um grande abraço e até mais. Fuiii !!!
Comentários
Postar um comentário