Programação em Shell Script

23 de jan de 2013 - Paulo Dias


O Shell Script é uma linguagem de programação utilizada principalmente para automatizar tarefas administrativas em sistemas operacionais Unix, Linux, BSD... Existem vários interpretadores para os scripts em shell, o mais utilizado em distribuições linux é o Bash, além dele, também é possível utilizar o Sh , Csh e o Ksh . Nesse artigo vou utilizar o Bash, veja um exemplo de Shell Script com Bash:

 
#!/bin/bash
echo "ola $USER";
 

Esse script simplesmente cumprimenta o usuário. Nele utilizei o comando "echo", que imprime na saída padrão ( nesse caso vai ser a tela do monitor ), e a variável de ambiente "$USER", que guarda o usuário logado. A primeira linha desse Shell Script, "#!/bin/bash", indica o interpretador que deve executar os comandos que estão no arquivo. é possível utilizar outro interpretador shell, por exemplo o "#!/bin/sh" ou um interpretador de outra linguagem como "#!/usr/bin/python"( seria possível usar até mesmo o PHP, veja um exemplo aqui ) ou não especificar nenhum interpretador, nesse ultimo caso, o sistema usa o interpretador que estiver na variável "$SHELL" ( interpretador padrão ).

Para testar esse script é necessário que ele tenha permissão de execução no sistema, para isso, supondo que o nome do arquivo seja "teste.sh" vou rodar no terminal o comando:


chmod +x teste.sh
 

e depois para executar o script vou usar o comando:


./teste.sh
 

Para executar o Shell Script coloquei o caminho completo do arquivo teste.sh ( o "./" representa o diretório atual ), isso foi necessário porquê quando é digitado um comando ( ou um Shell ) no terminal, sem especificar o caminho até o arquivo, o sistema busca por ele nos diretórios que aparecem no variável "$PATH". Se não quiser especificar o caminho para executar seus scripts, você pode colocá-los em um dos diretórios que aparecem na "$PATH" ou configurar o diretório onde eles estão nessa variável ( exemplo de como fazer isso aqui ).

Assim como outras linguagens de programação, Shell Script possui estruturas de controle do tipo: if, case, while e for. A Sintaxe dessas estruturas é a seguinte:

If
#!/bin/bash
nome="paulo";
if [ $nome != "paulo" ] ; then

  echo "vc não é o paulo!";
fi
 
Case
#!/bin/bash
i=1;
case $i in 

 1)
    echo "é 1";
 ;;
 
 2)
    echo "é 2";
 ;;

 *) 
    echo "não eh 1 nem 2";
 ;;
esac

While
#!/bin/bash
i=1;
while [ $i -le 10 ] ; do 

  echo $i;
  i=$(( $i + 1 ));
done

For
#!/bin/bash
for i in $( seq 10 ) ; do 

  echo $i;
done 

Em Shell Script os espaçamentos que normalmente são permitidos em outras linguagens causam erros, por exemplo quando é criada uma variável não deve haver espaços entre o nome da variável, o sinal de igual e o valor atribuído.

#!/bin/bash
i=1;   # ok, vai funcionar
j = 2; # não vai funcionar

Obs. é possível utilizar o comando "read" para ler da entrada padrão( geralmente o teclado ) e criar variaveis especificadas pelo usuário. Veja mais sobre isso aqui

Outra particularidade do Shell Script é que operações matemáticas não são realizadas diretamente, é necessário utilizar algum comando para realizar o calculo, por exemplo:

#!/bin/bash
i=1;   
j=$(( $i + 1 ));    # ok
j=$( expr $i + 2 ); # ok
j=$i + 1;           # não vai funcionar como esperado

Nesse exemplo foi utilizado o comando "$( expr $i + 2 )", basicamente trata-se de um sub-shell, o que estiver dentro de "$( )" é executado à parte e o resultado( o que seria impresso na saída padrão) é atribuído para variável. Também seria possível utilizar o comando "` expr $i + 2 `" para ter o mesmo resultado.

Outro detalhe importante que foi visto nos exemplos anteriores são os operadores usados nas estruturas de controle dentro do comando "[ ]", que na verdade é um açúcar sintático para o comando "test", veja alguns exemplos de operadores:

Para Numeros
-lt É menor que (LessThan)
-gt É maior que (GreaterThan)
-le É menor ou igual (LessEqual)
-ge É maior ou igual (GreaterEqual)
-eq É igual (EQual)
-ne É diferente (NotEqual)
Para Strings
= É igual
!= É diferente
Testes logicos
! Negação
-a and ( geralmente && )
-o or( geralmente || )
O Shell Script também possui funções, elas tem a seguinte sintaxe:
#!/bin/bash

function somar() {

  echo $(( $1 + $2 ));  
}

somar 1 2

As funções em Shell Script são chamadas da mesma forma que um comando, elas recebem parâmetros sem a necessidade de especificá-los na declaração da função. Os parâmetros são recuperados através de variáveis especais, como a "$1" e a "$2" utilizadas no exemplo acima. Veja outras dessas variáveis especiais:

$0 O nome da função
$1 O primeiro parâmetro
$2 O segundo parâmetro
$numero O parâmetro da posição numero
$# A quantidade de parâmetros
$* Todos os parâmetros

O script anterior poderia ter sido escrito da forma abaixo para não limitar o número de parâmetros a ser somados:

#!/bin/bash

function somar() {

  resultado=0;
  for i in $* ; do

    resultado=$(( $resultado + $i ));
  done

  echo $resultado;
}

somar 1 2 3 4 5

Uma observação importante sobre as funções em Shell Script é que apesar de possuir a instrução "return", essa instrução é utilizada de uma forma diferente. Em Shell Script funções são como os comandos, os comandos tem um código de retorno que indica se o comando foi executado corretamente ou não( isso é testado com a variável "$?" ), portanto as funções também tem esse código de retorno, que é retornado com a instrução "return" :)

Para conseguir armazenar o retorno de função em uma variável costumo usar o sub-shell:

#!/bin/bash

function somar() {

  resultado=0;
  for i in $* ; do

    resultado=$(( $resultado + $i ));
  done

  echo $resultado;
}

#usando o sub-shell é possível 
#armazenar o retorno da função 
total=$( somar 1 2 3 4 5 );

A grande utilidade das funções é que elas organizam e garantem a reutilização de código. Uma possibilidade interessante que o Shell Script permite( e a maior parte das linguagem de script também ) e incluir um arquivo dentro de outro ( parecido com o require e include do PHP). Por exemplo, posso criar varias funções que estejam relacionadas e coloca-las no mesmo arquivo e depois quando for necessário uso a instrução "source" para incluir essas funções em outro arquivo. Supondo que a função "somar" estivesse no arquivo matemática.sh posso usá-la da seguinte maneira:

#!/bin/bash

source "matematica.sh";

total=$( somar 1 2 3 4 5 );

Além de funções e estruturas de controle, Shell Script também possui arrays. Os arrays tem a seguinte sintaxe em Shell Script:

#!/bin/bash

dias=( "domingo" "segunda" "terca" "quarta" "quinta" "sexta" "sabado" );

echo ${dias[1]}; # imprime segunda

nomes[0]="paulo";
nomes[1]="ana";
nomes[2]="carlos";

echo ${nomes[1]}; 

# para retornar a quantidade de itens
echo ${#nomes[@]}  # imprime 3

Vou terminar deixando um script com o que foi visto nesse artigo, se quiser saber mais sobre Shell Script veja os links mais abaixo. Até mais... :)

#!/bin/bash
function organiza() {

 array=($@);
 i=0;
 while [ $i -lt ${#array[@]} ]; do

    j=$(($i + 1));
    while [ $j -lt ${#array[@]} ]; do
   
       if [ ${array[$j]} -lt ${array[$i]} ]; then 
   
          aux=${array[$j]};
          array[$j]=${array[$i]};
          array[$i]=$aux;   
       fi 
       j=$(($j + 1));
    done
    i=$(($i + 1));
 done

 for n in ${array[@]}; do

    echo "$n";
 done
}

organiza 2 9 4 5 6 1 

Mais Informações:
http://aurelio.net/shell/canivete/pdf/canivete-shell.pdf
http://thobias.org/doc/shell_bd.html
http://thobias.org/doc/cgi_shell.html
http://www.vivaolinux.com.br/dica/Utilizando-arrays-em-shell-script
http://lendscripts.blogspot.com.br/
http://victor-dba.blogspot.com.br/2012/02/10-dicas-para-programar-em-shell-script.html

Paulo Dias

Graduado no curso tecnólogo em análise e desenvolvimento de sistemas. Defensor do Software Livre e da democratização da informação. Possui as certificações Linux LPIC-1 e Java OCA. Atualmente exerce a função de coordenador técnico na área de telecomunicações.

Siga-me no Twitter