Você está na página 1de 7

Introduo Pretendo deixar mais claro como utilizar funes em shell, tambm pretendo abordar temas como retorno

da funo, declarao de constantes, variveis locais, variveis globais, argumentos para as funes etc. Espero que essa contribuio possa ajudar algumas pessoas no futuro. Todos os testes e exemplos mostrados aqui foram feitos em: Debian GNU/Linux SID Bash version 3.1.17

O que so funes
Funo nada mais que um cdigo escrito para resolver uma pequena parte de um problema, o que resolve o problema por inteiro chamado de software, o que faz pequenas coisas em um software so as funes. Uma coisa que no est na definio acima que a funo sempre encapsulada, ou seja, ela tem uma estrutura prpria que varia de linguagem para linguagem, porm normalmente segue uma forma mais ou menos parecida em todas estas.

Como declarar e usar uma funo dentro de um shell script


Para se criar uma funo dentro de um shell script basta fazer: function minha_funcao(){ echo 'minha funcao'; } Com esta declarao criamos uma funo chamada "minha funo", como pode ser visto ela apenas imprime a frase 'minha funcao'. A palavra "function" que precede o nome da funo opcional, porm para melhor visualizao sempre interessante mant-la, afinal escrever est pequena palavra no atrapalhar a sua vida, mas facilitar na hora de rever o script. Aps isso, para usar a funo basta colocar no seu script o nome dela: minha_funcao No use '()' quando cham-la, para o bash a funo como um comando, e esse o motivo de apenas usarmos o nome, e no como na maioria das linguagens acabamos usando 'minha_funcao(args)'.

Um ponto importante que a funo deve ser declarada antes de ser usada, algumas linguagens deixam que a funo esteja em qualquer lugar do cdigo, em shell ela sempre deve vir antes da primeira utilizao, por motivos de organizao deixe as funes no comeo do script, no crie funes no meio, nem no fim, coloque-as sempre no comeo, essa com certeza uma boa prtica. Vamos testar e ver o resultado: $ function minha_funcao(){ echo 'minha funcao'; } $ minha_funcao minha funcao Tudo funcionou como imaginvamos, agora vamos ver como o bash armazenou a funo: minha_funcao () { echo 'minha funcao' } Como pode ser visto, ele criou uma estrutura sem o 'function' precedendo o nome da funo, e tambm inseriu quebras de linhas.

Como passar argumentos para a funo? E o retorno da funo? Como disse anteriormente, o shell trata uma funo como se fosse um comando, ou seja, para se passar os argumentos basta fazer como fazemos todos os dias no terminal: minha_funcao arg1 arg2 .. argn O recebimento dos argumentos feito como se estivssemos passando estes para um script, temos ento que os argumentos sero passados para 'minha_funcao' como $0 $1 .. $n. No vou falar aqui como tratar os argumentos, vou apenas ensinar como so utilizados, s vezes no precisamos nos preocupar como estes acabam sendo passados, porm podemos querer maior controle sobre os argumentos, e talvez utilizar um getopts seja uma boa soluo, mas prefiro no entrar em detalhes aqui. Vamos "melhorar" um pouco a funo 'minha_funcao': function minha_funcao(){ for i in $* do echo $i done }

Agora vamos execut-la: $ minha_funcao a b c a b c bem simples a parte de passagem de argumentos, vamos s ver novamente como o bash armazenou a funo: minha_funcao () { for i in $*; do echo $i; done } Vamos lidar agora com o retorno da funo, como a maioria das linguagens o shell tem o famoso 'return' nas suas funes, porm com algumas diferenas que devem ser lembradas. A primeira coisa a saber que o 'return' s pode retornar inteiros, no h nenhum outro valor que possa ser usado, isso uma limitao do shell, se voc pensava em retornar strings, nmeros(reais), arrays, bem isso pode ser feito, porm no com o return. Para ser mais exato a funo do 'return' fica muito parecida com uma funo boolean em C, no nosso caso vamos usar um esquema desses, mais precisamente '0' funcionou, '1' no funcionou. O valor que retornado pelo 'return' vai para a varivel '?', vamos mostrar um exemplo de uma funo que use 'return': function verdade(){ [ $1 ] && return 0 || return 1 } Agora uma execuo da funo: $ verdade a $ echo $? 0 $ verdade $ echo $? 1 Basicamente essa funo retorna 0 se existir um argumento, e retorna 1 caso no exista. Vamos agora brincar com retornos de outros tipos, vamos modificar a funo 'verdade' para o nosso

exemplo: function verdade(){ [ $1 ] && echo 'verdade' || echo 'mentira' } Vamos mostrar a execuo: $ verdade mentira $ verdade a verdade Agora temos um retorno de qualquer tipo, normalmente armazenamos em uma varivel: $ TRUE=$(verdade) $ echo $TRUE mentira Cuidado ao fazer isso, pois todos os echos sero postos na varivel como no exemplo abaixo: function verdade(){ echo verdade; echo mentira; echo buga; } Execuo: $ verdade verdade mentira buga $ TRUE=$(verdade) $ echo $TRUE verdade mentira buga

Variveis globais X variveis locais X constantes Variveis globais so aquelas que podem ser vistas por qualquer funo, e/ou por qualquer parte do script. Variveis locais so usadas somente dentro de uma funo e tem precedncia sobre as variveis globais, isso quer dizer que se declararmos VAR globalmente, e depois declararmos VAR localmente, o shell usar a varivel local, lembre-se disso. Constante, como o prprio nome diz, uma constante, ela no pode ter seu valor alterado de nenhuma forma no decorrer da execuo do script.

Para criarmos uma varivel global basta declararmos normalmente a varivel, exemplo: TRUE='0' FALSE='1' Com isso as duas variveis acima podem ser vistas em qualquer lugar do cdigo. Para criamos uma varivel local devemos primeiro declar-las dentro de uma funo, e antes do nome da varivel devemos usar a palavra local, exemplo: function minha_funcao(){ local TRUE='verdade' local FALSE='falso' echo $TRUE echo $FALSE } Vamos ver o funcionamento da precedncia: $ TRUE='0' $ FALSE='1' $ function minha_funcao(){ local TRUE='verdade'; local FALSE='falso'; echo $TRUE; echo $FALSE; } $ echo $TRUE 0 $ echo $FALSE 1 $ minha_funcao verdade falso O uso de variveis locais muito importante, pois assim facilita a reutilizao do cdigo, alm de ajudar na criao de uma biblioteca de funes, pois usando variveis locais voc evitar o conflito entre variveis, ento altamente recomendado que sempre que for criar uma varivel dentro de uma funo que ela seja local, evite o mximo possvel o uso de variveis globais. Vamos agora ver um pouco sobre as constantes. As constantes podem estar em qualquer parte do cdigo, porm assim como as variveis globais prefervel que elas sejam declaradas no comeo do cdigo, isso se aplica as funes, ou seja, se precisar de uma constante coloque-a no comeo da funo e de preferncia sendo uma constante local. Para se declarar uma constante devemos fazer: declare -r <nome_da_constante>=<valor>

Exemplo: declare -r CONSTANTE='sempre igual' O comando declare uma funo interna do bash, h outras opes, mas novamente prefiro no entrar em detalhes. No nosso caso a opo '-r', diz que a varivel somente leitura (readonly). Vamos ver o que ocorre se tentamos mudar ou deletar uma constante: $ declare -r CONSTANTE='sempre igual' $ CONSTANTE='mude' bash: CONSTANTE: readonly variable $ unset CONSTANTE bash: unset: CONSTANTE: cannot unset: readonly variable Para declararmos uma constante local fazemos: function minha_funcao(){ local -r TRUE='verdade' local -r FALSE='falso' echo $TRUE echo $FALSE TRUE='nem vem' FALSE='isso ai cara' } A execuo resultante : $ minha_funcao verdade falso bash: TRUE: readonly variable

WORKAROUNDs Um dos problemas que tive que vale a pena ser documentado aqui foi quando uma das minhas funes tinha o mesmo nome que um comando, o bash sempre d preferncia a funo e nunca ao comando, voc tm algumas opes, a primeira e a mais simples mudar o nome da funo, porm digamos que na verdade essa funo est em uma biblioteca que voc fez, e que diversas pessoas j esto utilizando, mudar o nome quebraria diversos programas que esto funcionando corretamente, infelizmente voc foi bem infeliz e deu o nome de 'sort' para a sua funo. Bem, algum precisa usar o comando sort, e sua biblioteca juntos, o que fazer se no pudermos mudar o nome?

A primeira coisa que pensei foi em fazer um SORT=$(which sort), essa a melhor soluo que encontrei para esse problema. Outra situao que me deparei foi bem parecida com essa, o grande problema que algum teve a infeliz idia de chamar a funo de 'cd'; como o comando cd do prprio bash, ele no retorna nada quando fazemos 'which cd'; sendo assim a soluo acima no funcionaria, o que fiz foi utilizar outro comando do shell o 'builtin', esse comando chama qualquer builtin do bash ignorando a funo do mesmo nome. http://www.vivaolinux.com.br/artigos/impressora.php?codigo=8452

Você também pode gostar