if - dicas e scripts utilizando if.

Atualizado em: 12/05/2007



Sobre este documento

Exemplos de uso do if, linhas de comando e scripts.

exemplos de uso do if

Consulte a página do manual, tem a lista de todos operadores lógicos.

man bash

controle de fluxo utilizando if

  
  if [ condição ]; then
    #seus comandos aqui
  fi
  
  if [ condição ]
    then
    #seus comandos aqui
  fi
  
  if [ condição ]
    then
    #seus comandos aqui
  else
    #seus comandos aqui
  fi
  
  if [ condição ];then
    #seus comandos aqui
   else
    #seus comandos aqui
  fi
  
  if [ condição ];then
      #seus comandos aqui
    elif
      #seus comandos aqui
    else
      #seus comandos aqui
  fi

operaradores para arquivos e diretórios

Operadores if em testes com arquivos.

  -d  se é diretório
  -f  se o arquivo existe
  -o  dono do arquivo (owner) 
  -r  se tem permissão leitura
  -w  se tem permissão para gravar
  -x  se executável
  -z  se arquivo vazio

Veja também sobre test, comparar $UID com zero para saber se está executando como root e etc...

testar retorno do ultimo comando

Cada comando executado em shell tem um codigo de retorno, útil em script para conferir se falhou ou foi executado com sucesso, este resultado fica armazenado na variavel $?, ele muda a cada comando, tanto faz se foi na linha de comando ou dentro do script, atualizado a cada comando, echo $? exibe o resultado do ultimo comando, retornando:

   0 (zero) significa que o comando anterior foi executado com sucesso.
   1 (um) e qualquer valor diferente de zero ( != 0) indica que ocorreu algum    erro.
   2  erro nos comandos do script, geralmete erro de sintaxe, digitação,
   127 = command not found, quando digita comando não existente.

Exemplos:

  [zago@faqcl10 tmp]$ touch meuteste
  [zago@faqcl10 tmp]$ echo $?
  0
  [zago@faqcl10 tmp]$ ls meusdoc
  ls: meusdoc: Arquivo ou diretório não encontrado
  [zago@faqcl10 tmp]$ echo $?
  1
  [zago@faqcl10 tmp]$ ls
  meuteste
  [zago@faqcl10 tmp]$ echo $?
  0

Explicando:

retornou 1 (um) quando falhou o comando "ls meusdoc" e retornou zero para os demais comandos que foram executados sem problemas.

Cuidado para não repetir "echo $?" porque ele também é um comando e altera o retorno, portanto vale somente o primeiro "echo $?" depois do comando.

Alguns exemplos utilizando $?

  cat /tmp/testar
  #!/bin/bash
  mkdir /tmp/teste
  if [ $? -eq 0 ];then
    echo $?
    echo "comando executado com sucesso!"
  else
    echo $?
    echo "falha na execução do comando."
    exit
  fi

Neste exemplo a linha "if [ $? -eq 0 ]" verifica o retorno do comando "mkdir /tmp/teste", se foi bem sucedido ou não.

Na primeira vez que executar retorna zero de bem suscedido, depois passa a retornar 1 porque o diretório já existe e o comando falha na criação dele.

Invertendo o teste, testando se o retorno é diferente de zero, aplicando ls em um diretório que não existe, portanto tem que retornar valor diferente de zero.

  #!/bin/bash
  ls /home/dirquenaotem
  if [ "$?" != 0 ]
  then
     #seus comandos aqui
     echo "Erro - Saindo"
     exit 
  fi
  
  resultado:
  
  bash -xv testeif.sh
  #!/bin/bash
  ls /home/dirquenaotem
  + ls /home/dirquenaotem
  ls: /home/dirquenaotem: Arquivo ou diretório não encontrado
  if [ "$?" != 0 ]
  then
     #seus comandos aqui
     echo "Erro - Saindo"
     exit
  fi
  + '[' 2 '!=' 0 ']'
  + echo 'Erro - Saindo'
  Erro - Saindo
  + exit
  

testar se existe arquivo especifico no disco

man if encontra duas opções. -e e -f

         -e file
                True if file exists.
         -f file
                True if file exists and is a regular file.

-e é mais abrangente, funciona para arquivo, diretório e link.

-f é mais especifico, verifica somente arquivo normal, não testa diretórios e links.

if [ -e "/tmp/arqteste" ]; then echo "OK arquivo existe"; fi

testar se existe o arquivo /tmp/arqteste.txt, Retorna verdadeiro mesmo com arquivo vazio

touch /tmp/arqteste.txt

  #!/bin/bash
  arquivo='/tmp/arqteste.txt'
  if [ -f $arquivo ]
    then
    echo "OK arquivo encontrado"
  else
    echo "falhou - arquivo nao encontrado"
  fi

Testar com -e e aplicar comandos....

  #!/bin/bash
  if [ -e arqtemp.txt ]
  then
     #seus comandos aqui quando existir o arquivo.
     echo "arquivo encontrado."
  else
     #seus comandos aqui quando não existe o arquivo.
     echo "arquivo _não_ encontrado."
  fi
  
  Informando o caminho.
  
  #!/bin/bash
  if [ -e /tmp/arqtemp.txt ]
  then
     #seus comandos aqui quando existir o arquivo.
     echo "arquivo encontrado."
  else
     #seus comandos aqui quando não existe o arquivo.
     echo "arquivo _não_ encontrado."
  fi

tamanho de arquivo e comparações

Colocar o tamanho do arquivo em variavel para comparações.

Gravar CD e testar tamanho da ISO.

  #!/bin/bash
  # pegar tamanho do arquivo
  arqtam=$(du cl10_cd1.iso | awk '{print $1}')
  # comparar se maior que 600000
  if [ $arqtam -gt 600000 ]; then
    echo " arquivo maior que o limite do CD"
    exit 1
  else
    echo " tamanho OK, gravando CD"
    # comandos para gravar CD.
  fi

executando como root

Testar se está executando o script como root.

if test $UID = 0 verifica se está executando o script como root, quando executado por outro usuário, executa as linhas que vem depois do (else) e sai, neste exemplo emite o aviso que requer poderes de root.

Exemplo de script para criar usuários e testar se está sendo executado pelo root.

  #!/bin/bash
  if test $UID = 0
  then
     # criar usuário via linha de comando muda conforme a distro, ajuste para sua instalação.
     useradd -m $1  # suse 10.1
  #   adduser $1    # CL 10
     echo $2 | passwd $1 --stdin
     echo echo "Usuário $1 adicionado com sucesso"
  else
     echo Pra criar usuários requer poderes de root.
  fi

Este script está ajustado para SUSE 10.1. Linha de comando para executar o script com nome caduser, criar o usuário zago com a senha minhasenha, como root no console a linha de comando ficaria assim:

sh caduser zago minhasenha

Outro exemplo, testar se está executando com usuário diferente de root.

  #!/bin/bash
  if [ $UID != 0 ]
  then
     echo "Usuário diferente de root"
     exit
  fi

hora atual - testar

Ideal em scripts que deseja determinar a hora de inicio e fim, testa toda hora e executa os comandos do script.

Testar o conteúdo da variável, deve retonar somente a hora cheia como neste exemplo que foi executado às 20:08 horas.

  HATUAL=`date +%H`
  echo $HATUAL

retorna 20

Exemplo para disparar bittorrent as 19:00 horas e matar o processo as 07:00 horas.

Este script não inicia bittorrent pelo crontab, funciona com outras aplicaões, em breve procuro pelo erro do torrent e removo este aviso.

  HATUAL=`date +%H`
  if [ $HATUAL = "19" ]; then
    #seus comandos aqui, exemplo para download SUSE 10.1 em 5 CD.
    cd /home/zago
    btdownloadheadless --url http://download.opensuse.org/distribution/SL-10.1/SUSE-Linux-10.1-GM-i386.torrent
  
  fi
  # matar o processo
  if [ $HATUAL = "07" ]; then
    kill -9 $(ps ax|grep "python"|awk '{print $1}')
  fi

Crie o script com o conteúdo acima, salve no diretório /etc/cron.hourly, torne executável com chmod 755, para script com nome torrent.sh execute.

chmod 755 /etc/cron.hourly/torrent.sh

Também precisa trocar o endereço do torrent para o que deseja baixar, acertar o hora de iniciar e matar o processo.

testar dia da semana

Pegar o do dia da semana em formato numérico

MNUMDIA=$(echo `date +%u`)

echo $MNUMDIA

para quinta-feira retorna o numero 4

Onde:

  1=segunda
  2=terça
  3=quarta
  4=quinta
  5=sexta
  6=sábado
  7=domingo

Exemplo de rotina para testar em script se o dia é igual a Domingo (7), caso seja, emite uma mensagem e sai do script sem executar os demais comandos, ideal para rotinas de backup com exclusão do Domingo, inclua esta rotina no inicio do seu script, ajuste a mensagem a seu modo.

  #!/bin/bash
  MNUMDIA=$(echo `date +%u`)
  if [ $MNUMDIA = "7" ]; then
    echo "Domingo não é dia de trabalho nem de backup, saindo do script"
    echo "Domingo não tem backup, saindo do script" >> /tmp/logbackup.txt
    exit 1
  fi

Testar dois dias da semana, neste exemplo 6 para sabado e 7 para domingo, nestes dias executa dos comandos dentro do if, neste exemplo exibe uma mensagem, grava um registro em logbackup.txt e sai do script sem executar os demais comandos.

  #!/bin/bash
  MNUMDIA=$(echo `date +%u`)
  if [ $MNUMDIA = "6" -o $MNUMDIA = "7" ]; then
    # seus comandos aqui para executar nos dias testados pelo if.
    echo "Aos sabados e domingos não tem backup, saindo do script"
    echo "hoje é sab ou dom, saindo do script" >> /tmp/logbackup.txt
    exit 1
  fi

Amarrar script ao MAC da placa de rede

Tenho alguns scripts que quero executar em maquinas especificas, a forma mais prática que encontrei, amarrar o script ao MAC ADRESS da placa de rede, tem outras opções, pelo MAC é uma boa maneira de identificar a maquina.

Conferir se realmente é igual, no exemplo abaixo, compara o MAC da maquina com este "00:08:54:2C:DD:FD"

  #!/bin/bash
  MEUMAC=`LC_ALL= LANG= /sbin/ifconfig eth0 | grep HWaddr | awk '{print $5}'`
  if [ $MEUMAC = "00:08:54:2C:DD:FD" ]; then
    echo "estou na maquina que deve rodar o script"
    #seus comandos aqui
  else
     echo "MAC não confere, maquina diferente, altere o MAC no script"
  fi

Outra forma de testar, se o grep achou o MAC, se pegou alguma informação ou não.

  #!/bin/bash
  meumac=`ifconfig | grep "00:08:54:2C:DD:FD"`
  if [ -n "$meumac" ]; then
    echo "estou na maquina que deve rodar o script"
    #seus comandos aqui
  fi

if [ -n "$meumac" ] permite testar se variável meumac tem alguma informação diferente de vazio ou nulo, -n "$meumac" = não vazio nem nulo, se tiver alguma informação é porque o grep encontrou o MAC especificado. portanto identificando a maquina.

Como não tem (else), se não conferir com o MAC, não executa os comandos e sai sem mensagem.

comparar variáveis ou arquivos

if [ $IPATUAL != $ARQUIVOIP ] verifica se $IPATUAL é diferente de $ARQUIVOIP

Script que utiliza esta comparação.

  [zago@mailserv zago]$ cat /tmp/ipteste
  #!/bin/bash
  cd /tmp
  ARQUIVOIP=`cat /tmp/iparquivo`
  # ultimo ip enviado
  # estação com IP 192.168.1.3, precisa buscar o IP na net
  wget http://whatismyip.com/ -q -O ipatual
  cat ipatual | grep "<TITLE" | awk {'print $3'} > /tmp/ipatual.txt
  IPATUAL=`cat /tmp/ipatual.txt`
  # comparar IP atual com iparquivo
  echo $IPATUAL
  echo $ARQUIVOIP
  if [ $IPATUAL != $ARQUIVOIP ]
    then
    echo $IPATUAL
    # enviar e-mail
    DESTINATARIO="zagolinux@gmail.com"
    ASSUNTO="Novo IP de .."
    MENSAGEM="Novo IP $IPATUAL"
    echo "$MENSAGEM" | mail -s "$ASSUNTO" "$DESTINATARIO"
    echo $IPATUAL > /tmp/iparquivo
  fi

testar arquivos

Comparar datas de arquivos para saber qual é mais recente.

  if test arq1 -nt arq2 ; then
     #seus comandos aqui para quando arq1 for mais novo que arq2
     echo "arq1 é mais novo que arq2"
  fi

comparar com a-z A-Z

  #!/bin/bash
  MVAR="LETRAS"
  if [[ ${MVAR:0:1} = [A-Za-z] ]]; then
    echo "o primeiro caracter é uma letra em ${MVAR:0:1}"
    #seus comandos aqui
  else
     echo "Não é letra em ${MVAR:0:1}"
  fi

No exemplo acima compara toda faixa de de A a Z e de a a z.

if com expressões regulares funciona melhor com [[ ]]

Comparar se digitou s S ou n N

Exemplo para script que requer confirmação, com a tecla s ou S prossegue, qualquer outra tecla encerra o script.

  #!/bin/bash
  echo "Confirma [s/n]: "
  read -n1 MCONFIRMA
  if [ "$MCONFIRMA" = "S" -o "$MCONFIRMA" = "s" ]; then
      # seus comandos aqui.
      echo "confirmado, prosseguindo..."
    else
     echo "encerrando script, teclou $MCONFIRMA"
     exit 1
  fi

Para não sair do script remova a linha (exit 1), em lugar da mensagem (confirmado) inclua as linhas de comando; tais como copiar, mover, remover...

-n1 força um enter depois de teclar um caractere, sem ele permite teclar mais de um caracter e precisa teclar enter, veja o que diz o manual.

-n nchars

read returns after reading nchars characters rather than waiting for a complete line of input.

De outra forma mais simplificado, sem else e validando somente s minusculo.

  #!/bin/bash
  echo "Confirma [s/n]: "
  read -n1 MCONFIRMA
  if [ "$MCONFIRMA" = "s" ]; then
      # seus comandos aqui.
      echo "confirmado, executando..."
  fi

comparar numeros, nemor, maior, and, or

Conferir se o numero informado está entre determinada faixa, exemplo para comparar se 1980 está entre 1970 e 2000

  #!/bin/bash
  MANO=1980
  if [ $MANO -ge 1970 -a $MANO -le 2000 ]; then
    echo "numero dentro na faixa de 1970  a 2000"
    #seus comandos aqui
  else
     echo "numero fora da faixa de 1970 a 2000"
  fi

test

test pode ser usado como uma forma de if

test faz parte do pacote coreutils

man test

test - verifica tipos de arquivos e compara valores

alguns exemplos.

  MVAR=1
  test "$MVAR" -eq 1 && echo IGUAL-1 || echo DIFERENTE-1

Quando o resultado for verdadeiro executa a primeira condição (&& echo IGUAL-1), quando for falso executa a segunda (echo DIFERENTE-1)

Troque echo no exemplo acima pelo comando/ação desejada.

test "$MVAR" -eq 1 && ls /tmp || ls ~/

  MVAR=2
  test "$MVAR" -eq 1
  echo $?
  1
  
  MVAR=2
  test "$MVAR" -eq 2
  echo $?
  0

Indicações

Página principal sobre script em geral (FAQ)
http://www.zago.eti.br/script/A-menu-scripts.html

Página principal deste site (FAQ)
http://www.zago.eti.br/menu.html