Pular para o conteúdo

Shell Script: Programação Simplificada – Parte II

Shell Script: Programação Simplificada – Parte II

Como prometido, continuemos com a segunda parte do artigo.

Variáveis Padrão do Ambiente

Existem inúmeras variáveis que são utilizadas por programas executados em um Shell. Um programa pode necessitar da variável $USER para identificar qual o nome do usuário que está executando um determinado programa. Usuários podem possuir permissões diferentes em diferentes programas. Outro exemplo comum é a utilização da variável $HOME, que define o diretório padrão de cada usuário no Sistema Operacional.

Algumas Variáveis Padrão do Ambiente

Variável $PATH

Esta variável contém a lista de diretórios que o Shell irá verificar toda vez que um programa for executado. Se o valor da variável $PATH for /bin:/usr/bin:/sbin e um usuário executar o comando “ls”, o Shell irá buscar por /bin/ls, /usr/bin/ls e finalmente /sbin/ls.

Uma diferença importante entre o DOS/WINDOWS é que a variável $PATH do Unix/Linux não inclui o diretório atual no PATH, sendo assim se um programa for executado e o mesmo não estiver em um diretório definido na variável $PATH, o Unix/Linux não conseguirá encontrá-lo.  Neste caso pode-se utilizar a chamada local do programa, utilizando o “./”.

$ bash
bash# ls
Applications       Library
Desktop             Movies
Documents        Music
Downloads        Parallels
Favorites           Pictures
Games              Public
bash# cat busca
ls -lart /home/
bash# busca
-bash: busca: command not found
bash# ./busca
92 15 Mar 09:37 ..
 1 31 Mai 14:20 .
bash#

Listagem 14. Verificando caminhos Default ($PATH)

Variável $PWD

A variável $PWD é alterada cada vez que a sessão de um Shell troca de diretório, ou seja, esta variável sempre armazena o diretório atual de uma sessão.

Variável $TERM

Esta variável contém informações sobre o terminal que está sendo utilizado em uma sessão aberta. Se for utilizado um programa que emula um terminal “xterm”, então a variável $TERM mostrará o conteúdo xterm.

Variável $Shell

Esta variável armazena o Shell em utilização: bash, sh, csh, etc.

Prós da utilização de Shell Script

A maioria das tarefas que se repetem são boas candidatas para criação de scripts Shell. Scripts  não se esquecem de passo algum. Scripts Shell funcionam mais rapidamente, cometem menos erros e podem focar em tarefas específicas de um script.

Mesmo que uma determinada tarefa necessite de parâmetros diferentes em situações diferentes, pode-se adaptar um script Shell para receber, tratar e alterar estes parâmetros.

Scripts Shell podem ainda atender demandas para pequenas ou grandes necessidades. Uma rotina composta de muitas tarefas pode ser dividida em vários scripts que se relacionam e resolvem uma tarefa complexa, isso não só automatiza a execução da tarefa, mas também diminui a chance de pontos de falha.

Portabilidade é outra vantagem de utilizar scripts Shell. Pode-se utilizar o mesmo script em diferentes plataformas UNIX ou LINUX, uma vez que pode-se escolher o Shell conforme necessidade de cada plataforma.

Contras da utilização de Shell Script

Uma recomendação válida para a programação Shell script é manter os scripts curtos. Para um programa ou tarefa muito complexo (ex: 1000 linhas) é mais interessante utilizar linguagens mais estruturadas como Perl, Python, etc.

Scripts Shell são bons para processar comparativos entre strings, processar arquivos textos, tratar variáveis entre outras. De qualquer forma é um recurso limitado para calcular operações aritméticas, onde deve-se tomar um cuidado especial com números decimais, neste caso recomenda-se uma linguagem mais estruturadas.

Executando Scripts Shell

Uma vez criado o script, o mesmo pode ser executado de várias maneiras. Primeiro, pode-se passar como um argumento do Shell:

$ bash nome_do_script.sh

Listagem 15. Executando scripts especificando o nome do Shell

Pode-se também executar o script de maneira direta:

$ ./nome_do_script.sh

Listagem 16. Executando scripts de maneira direta

Quando um script é executado diretamente, o Shell procura pelo “número mágico” (#!) na primeira linha do script. Se este caractere existir, então o script irá utilizar o Shell especificado. Caso este caracter não existir, então o script será executado no Shell da sessão atual / padrão. É extremamente recomendável especificar o Shell desejado em todos os scripts desenvolvidos.

#!/bin/bash
ls –lrt /home/oracle
sqlplus / @teste.sql
exit

Listagem 17. Especificando o Shell dentro de Scripts

É importante lembrar que para executar um script qualquer, o mesmo deve possuir permissões para execução. Essas permissões devem ser concedidas através do comando “chmod”:

$ chmod a+c nome_do_script.sh
$ chmod 755 nome_do_script.sh

Listagem 18. Garantindo permissões de execução para scripts Shell

Jobs e Alias

Todos os Shells ainda suportam a utilização de Jobs agendados ou não, considerados como processos dentro do Sistema Operacional. Um Job tem por definição executar uma ou mais tarefas distintas ou ainda dentro de vários scripts Shell previamente criados. A função de um Job é facilitar a execução de tarefas repetitivas: Backups, Coletas, Relatórios, etc. Como um Job é um processo, cada Job possui seu PID específico no sistema operacional.

Existem três tipos de Jobs:  Primeiro Plano (Foreground), Segundo Plano (Background) e Parado (Stopped).

Foreground: Este ocorre quando um Job é executado dentro de uma janela de terminal e utiliza esse terminal até o encerramento do Job, não permitindo assim a execução de outras tarefas neste terminal.

Background: Este ocorre quando um determinado Job é executado via agendador de tarefas (CRONTAB) ou manualmente porém a utilização do símbolo “&” ao final do comando. Neste caso o Job será colocado em processamento sem utilizar ou “bloquear” a utilização do terminal corrente, permitindo assim o usuário executar outras tarefas paralelas.

Stopped: Se durante a execução de um Job, no mesmo terminal, foi pressionado a combinação de teclas “CONTROL +Z” então este Job será parado  com status “stopped”, mas o processo no sitema operacional continuará aguardando a retomada ou encerramento do Job.

A utilização de Alias  é muito comum para facilitar a chamada de comandos com grande quantidade de parâmetros. Pode-se criar inúmeras aliases  em um Shell Unix ou Linux. Todas as aliases criadas são armazenadas pelo Shell e relacionadas aos comandos desejados. Existem algumas regras tais quais: Não podem existir espaços em branco ao lado do sinal de igualdade (=).  O comando de criação deve conter aspas caso o mesmo contenha parâmetros os metacaracteres. Cada comando de um único Alias deve ser separado por ponto e vírgula (;).

$ alias info=’uname –a; id; date’

Listagem 19. Exemplo de criação de Alias

Para remover um alias, deve-se utilizar o caracter () antes do nome do arquivo durante o comando “rm”.

A utilização de Alias não se restringe apenas em linha de comando dentro de um Terminal qualquer, um Alias pode ser utilizado dentro de scripts que compõem ou não um determinado Job.

Scripts dentro de Scripts

Todo e qualquer Script Shell por ser tratar de um programa computacional pode ser tratado com os mesmos conceitos de um programa comum.

Os scripts podem ser executados através de chamadas dentro de outros scripts de maneira direta, indireta ou com especificação do Shell. Pode-se também utilizar o conceito de recursividade dentro de programas escritos em Shell Script, onde um script para atuar conforme saída ou retorno do script anterior.

Este conceito de chamada recursiva é de comum uso com estruturas de controle como “for”, “while” e outras, onde o resultado de um script serve como entrada para outro script.

10 Dicas para Programar em Shell Script

É muito comum que em alguns casos, estes profissionais tenham dúvidas para desenvolver programas na linguagem Shell devido a dúvidas no conceito e funcionalidades do Shell (bash, csh, ksh, sh) no sistema operacional.

Para facilitar o entendimento e simplificar sua programação, existem algumas regras Básicas:

1 – Especificar qual Shell será utilizado

É pré-requisito em qualquer programa escrito em Shell SCRIPT definir qual será o Shell que será utilizado. Isso garante que o Sistema Operacional irá interpretar e executar todas as instruções do script com o interpretador correto.

#!/bin/bash

# Procedimento - Backup Database FULL.
# Data: 30-05-2012
# Por: Victor Armbrust
# VictorDBA.net

Listagem 20. Especificar qual Shell será utilizado

Na linha 1 o Shell é especificado.

2 – Comentários e descrição do Script

Esta sessão tem como objetivo descrever o objetivo do script e suas funcionalidades.  Isso ajudará o desenvolvedor a lembrar porque o script foi escrito, e para qual função.

#!/bin/bash
# Procedimento - Backup Database FULL.
# Data: 30-05-2012
# Por: Victor Armbrust
# VictorDBA.net

Listagem 21. Manter comentários e descrição do Script

Após a linha 1 é definida a descrição do script.

3 – Declara Variáveis 

É muito importante garantir que todas as variáveis necessárias para execução de seu programa sejam declaradas. É recomendável fazer esta declaração no início do script.

Lembre-se: Quando o script é executado será aberto um novo Shell, com isso, nenhuma variávei declarada na sessão atual será utilizada. Declarar variáveis é PRIMORDIAL, assim como em qualquer outra linguagem de programação.

#!/bin/bash

# Procedimento - Backup Database FULL.
# Data: 30-05-2012
# Por: Victor Armbrust
# VictorDBA.net
export TEMP=/tmp
export TMPDIR=/tmp
export ORACLE_SID=$1
export ORACLE_BASE=/u/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1
export PATH=$ORACLE_HOME/bin:$PATH:/usr/bin/usr/local/bin
export ORACLE_OWNER=oracle
case "$ORACLE_SID" in
pback1*)
export BKPDIR=/u5/backup/rman/pback
;;
pback2*)
export BKPDIR=/u5/backup/rman/pback
;;
*)
export BKPDIR=/backup/rman/${ORACLE_SID}
;;
esac
data=`date +%d%m%y%H`
LOG=/logs/backup_diario_${ORACLE_SID}_$data.log
DH=`date +%Y%m%d-%H%M`
DTIME=`date "+%m%d%y_%H%M"`
TAG=hot_disk_${ORACLE_SID}_${DTIME}

Listagem 22. Declarar todas as variáveis no início do script

Após a linha 5 é feita a declaração e tratamento de variáveis.

4 – Edentação

Muitas pessoas acreditam que edentar scripts não é necessário. Para garantir o funcionamento do script realmente não é, porém para entendimento próprio ou de outro analista que venha futuramente utilizer o script, é extremamente necessário. Edentação é sinônimo de organização e facilita o entendimento posterior.

case "$ORACLE_SID" in
     pback1*)
     export BKPDIR=/u5/backup/rman/pback
     ;;
     pback2*)
     export BKPDIR=/u5/backup/rman/pback
     ;;
    *)
    export BKPDIR=/backup/rman/${ORACLE_SID}
    ;;
esac

Listagem 23. Manter Edentação

5 – Comentários fase-a-fase

Procure descrever em comentários o que cada parte do script irá executar. Isso ajuda a realizer melhorias  e “debugar” possíveis problemas futuros.

Os comentários também ajudam a dividir o script em etapas e facilitam o entendimento de estruturas de controle, procedimentos, etc.

################################################
## Fase 1 - Apagar Backup Database $ORACLE_SID FULL ##
################################################

Listagem 24. Manter comentários fase a fase

6 – Logs

Mantenha logs de todos os seus scripts. Preferencialmente especificando o arquivo de LOG dentro do script, como variável. Para análise posterior em execuções será muito mais fácil encontrar possíveis erros.

Utilizar  arquivos de LOGs com controle de datas é uma maneira de organizer o histórico de execuções, prevenindo que logs de execuções anteriores sejam sobrescritos.

data=date +%d%m%y%H

LOG=/logs/backup_diario_${ORACLE_SID}_$data.log

DH=date +%Y%m%d-%H%M

Listagem 25. Geração de Logs

7 – Corpo do Script (Body)

Utilize suas variáveis declaradas no início do script. Isso ajuda a não fixar valores e facilita a alteração do script.

$ORACLE_HOME/bin/rman target / nocatalog <<EOF >> $LOG
RUN {
sql 'alter system archive log current';
sql 'alter system switch logfile';
BACKUP FORMAT '$BKPDIR/bkp_db.bkp' DATABASE TAG=${TAG};
BACKUP FORMAT '$BKPDIR/bkp_arc.bkp' ARCHIVELOG ALL TAG=${TAG};
BACKUP FORMAT '$BKPDIR/bkp_ctrl.bkp' CURRENT CONTROLFILE TAG=${TAG};
BACKUP FORMAT '$BKPDIR/spfile_%s_%p_%t' SPFILE TAG=${TAG};
}

Listagem 26. Utilização de Variáveis no corpo do script

8 – Validação da execução de cada comando

De nada adianta um script que executa 100 tarefas e nenhuma possui validação. Este é um dos “erros” mais comuns em programação Shell. Um commando executado sem análise de retorno (“Return Code”) não possui integridade alguma. Procure sempre analisar passo-a-passo sua execução.

RETVAL=$?
 if test "$RETVAL" != "0"
   then
     echo " " >> $LOG
     echo "****Erro Fase 2: Gerar Backup. returcode $RETVAL" >> $LOG
     echo " " >> $LOG
     exit 0
 fi

Listagem 27. Validar código de retorno

9 – Nomes Coerentes

Procure manter o nome de seus scripts de forma coerente. É sempre mais fácil para encontrar scripts que possuam relação entre seu nome e a atividade que o mesmo executa.

Ex:

Backup Hot Online Completo do Oracle Database

“bkp_rman_full.sh”

Backup de Todas as Tabelas do Oracle Database

“bkp_expdp_full.sh”

Listagem 28.Manter nomes de arquivos coerentes

10 – Validação das execuções de Scripts

Este provavelmente é o passo mais importante. Valide as execuções de seus scripts, acompanhe os logs (diários, mensais, etc), neles você poderá encontrar erros ou melhorias. Sempre que possível, implemente algum recurso de monitoração.

CRONTAB

As dicas acima são válidas também para execução de scripts via agendador de tarefas do Linux/Unix, o CRONTAB. O daemon “crond” é executado em Shell separado, e também exige que todos os comandos e variáveis sejam corretamente definidos.

Existem diversas regras e dicas que podem ser seguidas para otimizar as funcionalidades de seus scripts, essas são apenas algumas.

Procure sempre manter a organização e o fácil entendimento para que não ocorram futuros “desconfortos”.

Conclusões

A Programação Shell script pode ajudar de diversas maneiras na automatização de tarefas e administração de sistemas e aplicativos em plataformas UNIX e LINUX. Como demonstrado é extremamente importante dominar e ponderar a utilização deste recurso de programação, sempre visando melhorias em segurança e minimização de falhas. Existem inúmeros recursos disponíveis ao desenvolvedor em várias distribuições de cada Shell, é importante entendê-los para atingir resultados proveitosos.

Atualmente o Linux é um Sistema Operacional maduro e com grande utilização no mercado. Nas atuais distribuições o Shell mais utilizado é o Bourne-Again Shell, que é extremamente confiável e estável. É uma ótima opção para escrever scripts em Shell e definir estratégias para rotinas comuns do dia-a-dia.

Referências

  • Visão Geral sobre Shell Script http://pt.wikipedia.org/wiki/Shell_script
  • Learning the Korn Shell (2002 – 2nd Edition – 434pgs) O’Reilly Media, ISBN-10: 0596001959,Bill Rosenblatt, Arnold Robbins
  • Linux Command Line and Shell Scripting Bible, (2011 – 2nd Edition – 840pgs) Wiley, ISBN-10: 1118004426, Richard Blum, Christine Bresnahan
  • GNU Operating System http://www.gnu.org/software/bash/
Victor Armbrust

Victor Armbrust

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Marcações:
plugins premium WordPress