Revista Do Linux  
EDIÇÃO DO MÊS
 Produto
 LinuxTag
 Shell Script
 Entrevista
 CD do mês
 Capa
 Estudo de Caso
 Distribuições Diet
 Segurança
 Squid
 Corporativo
 Games

Mais fundo no Shell Script
Aumentando o poder dos scripts com novos comandos

No artigo passado falamos sobre o conceito da programação em Shell Script, e demos o primeiro passo para construir nossos próprios scripts. Agora vamos nos aprofundar nos comandos mais complicados, aprendendo a fazer programas ainda mais úteis. Nestes comandos estão inclusos o case e os laços for, while e until. Além disso, vamos falar de funções e, por último, teremos um programa em shell script.

Case

O case é para comando de fluxo, tal como é o if. Mas enquanto if testa expressões não exatas, o case vai agir de acordo com resultados exatos. Vejamos um exemplo:



case $1 in
 parametro1) comando1 ; comando2 ;;
 parametro2) comando3 ; comando4 ;;
 *) echo "Você tem de entrar com um parâmetro válido" ;;
esac


Aqui aconteceu o seguinte: o case leu a variável $1 (que é o primeiro parâmetro passado para o programa), e comparou com valores exatos. Se a variável $1 for igual ao parâmetro1, então o programa executará o comando1 e o comando2; se for igual ao parâmetro2, executará o comando3 e o comando4, e assim em diante. A última opção (*), é uma opção padrão do case, ou seja, se o parâmetro passado não for igual a nenhuma das outras opções anteriores, esse comando será executado automaticamente.

Você pode ver que, com o case fica muito mais fácil criar uma espécie de "menu" para o shell script do que com o if. Vamos demonstrar a mesma função anterior, agora com o if:



 if [ -z $1 ]; then
   echo "Você tem de entrar com um parâmetro válido"
   exit
elif [ $1 = "parametro1" ]; then
   comando1
   comando2
elif [ $1 = "parametro2" ]; then
   comando3
   comando4
else
   echo "Você tem de entrar com um parâmetro válido"
fi


Veja a diferença. É muito mais prático usar o case! A vantagem do if é que ele pode testar várias expressões que o case não pode. O case é mais prático, mas o if pode substituí-lo e ainda abrange mais funções. Note que, no exemplo com o if, citamos um "comando" não visto antes: o elif - que é uma combinação de else e if. Ao invés de fechar o if para criar outro, usamos o elif para testar uma expressão no mesmo comando if.

For

O laço for vai substituindo uma variável por um valor, e vai executando os comandos pedidos. Veja o exemplo:



for i in *
do
   cp $i $i.backup
   mv $i.backup /usr/backup
done


Primeiramente o laço for atribuiu o valor de retorno do comando "*" (que é equivalente a um ls sem nenhum parâmetro) para a variável $i, depois executou o bloco de comandos. Em seguida ele atribuiu outro valor do comando "*" para a variável $i e reexecutou os comandos. Isso se repete até que não sobrem valores de retorno do comando "*". Outro exemplo:



for original in *; do
   resultado=_cho $original | tr ‘[:upper:]’ ‘[:lower:]’>    if 
[$original != $resultado ]; then
      mv $original $resultado
   fi
done


Aqui, o que ocorre é a transformação de letras maiúsculas para minúsculas. Para cada arquivo que o laço lê, uma variável chamada $resultado irá conter o arquivo em letras minúsculas. Para transformar em letras minúsculas, usei o comando tr. Caso já exista um arquivo igual e com letras minúsculas, o arquivo é renomeado para o valor da variável $resultado, de mesmo nome, mas com letras minúsculas.

Como os exemplos ilustram, o laço for pode ser bem útil no tratamento de múltiplos arquivos. Você pode deixá-los todos com letras minúsculas ou maiúsculas sem precisar renomear cada um manualmente, pode organizar dados, fazer backup, entre outras aplicações.

While

O while testa continuamente uma expressão, até que ela se torne falsa. Exemplo:



 while [ $variavel = "valor" ]; do
   comando1
   comando2
done

O que acontece aqui é o seguinte: enquanto a "$variável" for igual a "valor", o while ficará executando os comandos 1 e 2, até que a "$variável" não seja mais igual a "valor". Se no bloco dos comandos a "$variável" mudasse, o while iria parar de executar os comandos quando chegasse em done, pois agora a expressão $variável = "valor" não seria mais verdadeira.

Until

Tem as mesmas características do while, a única diferença é que ele faz o contrário. Veja o exemplo abaixo:



until [ $variavel = "valor" ]; do
   comando1
   comando2
done

Ao invés de executar o bloco de comandos (comando1 e comando2) até que a expressão se torne falsa, o until testa a expressão e executa o bloco de comandos até que a expressão se torne verdadeira. No exemplo, o bloco de comandos será executado desde que a expressão $variável = "valor" não seja verdadeira. Se no bloco de comandos a variável for definida com o "valor", o until pára de executar os comandos quando chega ao done.

Vejamos um exemplo para o until que, sintaticamente invertido, serve para o while também:


var=1
count=0
until [ $var = "0" ]; do
   comando1
   comando2
   if [ $count = 9 ]; then
      var=0
   fi
   count=xpr $count + 1> done

Primeiro, atribuímos à variável "$var" o valor "1". A variável "$count" será uma contagem para quantas vezes quisermos executar o bloco de comandos. O until executa os comandos 1 e 2, enquanto a variável "$var" for igual a "0". Então usamos um if para atribuir o valor 0 para a variável "$var", se a variável "$count" for igual a 9. Se a variável "$count" não for igual a 0, soma-se 1 a ela. Isso cria um laço que executa o comando 10 vezes, porque cada vez que o comando do bloco de comandos é executado, soma-se 1 à variável "$count", e quando chega em 9, a variável "$var" é igualada a zero, quebrando assim o laço until.

Usando vários scripts em um só

Pode-se precisar criar vários scripts shell que fazem funções diferentes, mas, e se você precisar executar em um script shell outro script contido nele, para que este faça alguma função e não precise reescrever o código? É simples, você só precisa incluir o seguinte comando no seu script shell:



 .. bashscript2

Isso executará o script shell "bashscript2" durante a execução do seu script shell. Neste caso ele será executado na mesma shell em que está sendo usado o comando. Para utilizar outra shell, você simplesmente substitui o "." pelo executável da shell, assim:



sh script2
tcsh script3

linhas o script2 será executado com a shell sh, e o script3 com o shell tcsh.

Variáveis especiais

$0Nome do script que está sendo executado
$1-$9Parâmetros passados à linha de comando
$#Número de parâmetros passados
$?Valor de retorno do último comando ou de todo o shell script (o comando "exit 1" retorna o valor 1)
$$Número do PID (Proccess ID)

Você também encontra muitas variáveis, já predefinidas, na página de manual do bash (comando "man bash", seção Shell Variables).

Funções

Funções são blocos de comandos que podem ser definidos para uso posterior em qualquer parte do código. Praticamente todas as linguagens usam funções que ajudam a organizar o código. Vejamos a sintaxe de uma função:



funcao()
{
  comando1
  comando2
  ...
}

Fácil de entender, não? A função funcionará como um simples comando próprio. Você executa o comando função em qualquer lugar do script shell, e os comandos 1, 2 e outros serão executados. A flexibilidade das funções permite facilitar a vida do programador, como nesse exemplo final.

Exemplo Final

Agora vamos dar um exemplo de programa que utilize o que aprendemos com os artigos.



#!/bin/bash
# Exemplo Final de script shell
Principal()
{
   echo "Exemplo Final sobre o uso de scripts shell"
   echo "–––––––––––––––––––––"
   echo "Opções:"
   echo
   echo "1. Transformar nomes de arquivos    
  (Maiúsculo/Minúsculo)"
   echo "2. Adicionar um usuário no sistema"
   echo "3. Deletar um usuário no sistema"
   echo "4. Fazer backup dos arquivos do /etc"
   echo "5. Sair do exemplo"
   echo
   echo -n "Qual a opçao que deseja? "
   read opcao
   case $opcao in
     1) Transformar ;;
     2) Adicionar ;;
     3) Deletar ;;
     4) Backup ;;
     5) exit ;;
     *) echo "Opçao desconhecida." ; echo ; Principal ;;
   esac
}
# Funçao Transformar (1)
Transformar()
{
   echo -n "Transformar para maiúsculo ou minúsculo? 
   [M/m] "
   read var
   if [ $var = "M" ]; then
      echo -n "Que diretório? "
      read dir
      for x in /bin/ls $dir; do
         y=_cho $x | tr ‘[:lower:]’ ‘[:upper:]’
         if [ $x != $y ]; then
            mv $x $y
         fi
      done
   elif [ $var = "m" ]; then
      echo -n "Que diretório? "
      read dir
      for x in /bin/ls $dir; do
         y=_cho $x | tr ‘[:upper:]’ ‘[:lower:]’
          if [ $x != $y]; then
            mv $x $y
          fi
      done
   fi
}
# Funçao Adicionar (2)
Adicionar()
{
   clear
   echo -n "Qual o nome do usuário a se adicionar? "
   read nome
   adduser nome
   Principal
}
# Funçao Deletar (3)
Deletar()
{
   clear
   echo =n "Qual o nome do usuário a deletar? "
   read nome
   userdel nome
   Principal
}
# Funçao Backup (4)
Backup()
{
   for x in /bin/ls /etc>    do
      cp -R /etc/$x /etc/$x.bck
      mv /etc/$x.bck /usr/backup
   done
}
# Executa o menu principal
Principal






      

      
 

A Revista do Linux é editada pela Conectiva S/A
Todos os Direitos Reservados.

Política de Privacidade