14
www.howtoday.com.br SHELL SCRIPT A linguagem de programação Shell é um kit de ferramentas versáteis e de grande utilidade para o administrador, pois esta linguagem utiliza como interpretador de comando o próprio Shell do sistema e, sendo assim, pode executar todos os comandos de um terminal do Linux ou do Unix e ainda mais as suas próprias estruturas de análises lógicas, seus comandos próprios, interfaces gráficas, etc. Estas características todas fazem de um programa de Shell uma parte integrante do próprio sistema em si, uma vez que diversas rotinas administrativas podem ser interfaceadas por ele, como backups, regras de firewall, criação e administração de usuários em demanda, etc. Enfim, o Shell Script é totalmente aplicável a sistema. Antes de produzir o primeiro script, algumas ferramentas devem ser conhecidas: Aliases Os aliases substituem comandos ou parte de linhas de comandos. Eles são armazenados em memória e removidos dela no momento em que o usuário não está mais usando o terminal (logoff), por causa disto, para que haja persistência dos aliases, é preciso declará-los em algum arquivo de script de login de usuário, como foi visto em capítulo anterior. A sintaxe de criação de um alias é esta abaixo: #alias <nome do alias>=’comandos’ Para remover um alias: #unalias <nome do alias> Para executar o alias, basta digitar o nome dele como um comando, que pode, sem problemas ter argumentos também: #<nome do alias> Exemplos: Criando e executando o alias backup para fazer backup de todo o diretório /var/log para um aquivo chamado /backups/backup-var.tar.gz: #alias backup=’tar -czvf /backups/backup-var.tar.gz /var/log’ #backup

Shell Script Tutorial

Embed Size (px)

DESCRIPTION

Shell Script Tutorial

Citation preview

Page 1: Shell Script Tutorial

www.howtoday.com.br

SHELL SCRIPT

A linguagem de programação Shell é um kit de ferramentas versáteis e de grande utilidade para o administrador, pois esta linguagem utiliza como interpretador de comando o próprio Shell do sistema e, sendo assim, pode executar todos os comandos de um terminal do Linux ou do Unix e ainda mais as suas próprias estruturas de análises lógicas, seus comandos próprios, interfaces gráficas, etc. Estas características todas fazem de um programa de Shell uma parte integrante do próprio sistema em si, uma vez que diversas rotinas administrativas podem ser interfaceadas por ele, como backups, regras de firewall, criação e administração de usuários em demanda, etc. Enfim, o Shell Script é totalmente aplicável a sistema.

Antes de produzir o primeiro script, algumas ferramentas devem ser conhecidas:

Aliases

Os aliases substituem comandos ou parte de linhas de comandos. Eles são armazenados em memória e removidos dela no momento em que o usuário não está mais usando o terminal (logoff), por causa disto, para que haja persistência dos aliases, é preciso declará-los em algum arquivo de script de login de usuário, como foi visto em capítulo anterior.

A sintaxe de criação de um alias é esta abaixo:#alias <nome do alias>=’comandos’Para remover um alias:#unalias <nome do alias>Para executar o alias, basta digitar o nome dele como um comando, que

pode, sem problemas ter argumentos também:#<nome do alias>

Exemplos:

Criando e executando o alias backup para fazer backup de todo o diretório /var/log para um aquivo chamado /backups/backup-var.tar.gz:

#alias backup=’tar -czvf /backups/backup-var.tar.gz /var/log’#backup

Page 2: Shell Script Tutorial

www.howtoday.com.br

Criando um alias para tornar padrão o modo interativo do comando rm quando ele for digitado:

#alias rm=’rm –i’Neste caso, quando o comando for executado com qualquer que seja a

opção, será perguntado ao usuário se ele quer mesmo excluir o objeto.

Funções

Ao contrário dos aliases, as funções só conseguem armazenar comandos completos, ou seja: não aceitam argumentos na hora da execução.

As duas sintaxes possíveis para uma função são:#function <nome> { comandos; };ou#<nome> () { comandos; };É preciso tomar muito cuidado com os espaços entre as chaves e os

outros caracteres, pois se esta sintaxe não for mantida à risca, a função não funcionará.

Exemplos:

Criando e executando uma função para atualizar a base de dados do APT, instalar o pacote squid e depos limpar o cache:

#function instala_squid { apt-get update; apt-get install squid; apt-get clean; };

#instala_squid

Para excluir uma função, basta usar o comando unset:#unset <função>

Para exibir todas as funções criadas:#declare –f

Variáveis do Shell

O Shell do sistema trabalha o tempo inteiro lendo e gravando variáveis que vão ajudá-lo a interpretar melhor os comandos e as configurações existentes. Um exemplo sismples é a variável HOME do usuário, que é lida pela linha de comando cd ~ para que seja possível entender que ‘ ~ ‘ é o homedir do usuário em sessão, a cada vez que um usuário faz logon é criada esta variável com o caminho do diretório pessoal dele (independente de qual seja este usuário).Existem dois tipos de variáveis no Linux:

Variáveis GlobaisSão as variáveis que não dependem de sessão de usuário para existirem.

Estas variáveis podem ser consultadas através do comando set.Exemplos:LANG : variável que recebe o idioma do sistema e a codificação de

caracteres.LANGUAGE: variável de idiomas de teclado.HOSTNAME : hostname da máquina.

Page 3: Shell Script Tutorial

www.howtoday.com.br

Variáveis de ambienteSão aquelas que dependem do usuário para serem criadas, pois,

dependendo de quem seja o usuário, a variável não será a mesma, como as variáveis abaixo:

PATH : indica o caminho de busca dos comandos que são digitados pelo usuário. A variável PATH do usuário root contém os diretórios “sbin”, que a mesma variável para um usuário comum não tem, por padrão, pois os programas contidos em dietórios “sbin” são de uso exclusivo de root.

SHELL : aponta para a localização do arquivo binário do Shell do usuário.PWD : diretório atual do usuário.OLDPWD : diretório acessado anteriormente pelo usuário.HOME : diretório pessoal do usuário.A lista de variáveis de ambiente pode ser obtida com o comando env.

Criação e manipulação de variáveisDependendo do motivo do script, o usuário vai precisar que a variável

que ele esteja usando não sirva apenas para o seu próprio programa, mas seja também uma variável exportada para o sistema, então, a primeira providência que deve ser tomada é exportar esta variável com o comando abaixo:

#export <variável>=<valor>Este processo também pode ser feito em duas etapas: a criação e depois

a exportação da variável. Para isso, podemos usar as seguintes linhas de comando:

#<variável>=<valor>#export <variável>Toda vez que uma variável for utilizada, o $ deve vir antes do nome dela,

como no exemplo abaixo:#export LOGS=/var/log#cd $LOGS

Outro exemplo de manipulação de variável é a adição do diretório /programas na variável PATH do usuário para que comandos que estejam neste diretório possam ser executados de forma mais simples por ele:

#export PATH=$PATH:/programasMostrando o valor da variável:#echo $PATH

Para excluir uma variável que foi criada, basta utilizar também o comando unset, como no exemplo abaixo:

#unset LOGS

Criação de scripts

Um aquivo de script é um arquivo comum de texto e pode ser executado com qualquer extensão (.txt,.mp3,.ppt, etc..), até porque as extensões em Linux não têm funcionalidade nenhuma para execução ou leitura ou gravação em arquivos. Ainda que não utilizemos as extensões, para que o script de Shell possa ser lido pelo edito vim com cores de sintaxe é preciso que o arquivo de script tenha alguma extensão, mais especificamente a extensão .sh.

Page 4: Shell Script Tutorial

www.howtoday.com.br

Como os scripts de Shell serão utilizados em administração de sistema Linux como caixa de ferramentas, vamos já começar aplicando o seu uso para este fim, com o primeiro script abaixo, que será um programa para criar usuários:

#vim ~/cria_users.sh

Neste script, já se podem notar algumas características de Shell Script, como a inserção de comentários, que pode ser feita com o ‘#’. Eles são primordiais para a boa documentação dos scripts criados, pois podem ser usados para marcar a versão do script, as datas de criação e última modificação, o autor e a descrição do script que está sendo criado, como foi feito no exemplo acima.

É importante também que a informação de qual Shell vai interpretar os comandos esteja no cabeçalho com a seguinte sintaxe: #!<caminho do Shell>. No exemplo acima foi utilizado o Shell BASH, cujo binário está em /bin/bash. Poderia ter sido utilizado outro Shell disponível em /etc/shells, sem nenhum problema, mas como o BASH é o Shell padrão para comandos no Linux, é sempre melhor utilizá-lo como interpretador para os comandos que vão ser usados.

Alguns outros recursos usados acima serão analisados agora:#echo Este comando é responsável por produzir tanto STDIN (saída padrão de

comando) como STDERR (saída de erros de comando). Suas sintaxes são:#echo <valor de variável, saída de comando ou texto>#echo ”<valor de variável, saída de comando ou texto>”

Page 5: Shell Script Tutorial

www.howtoday.com.br

#echo ‘<texto>’

Exemplos:

Produzindo como saída o valor da variável SHELL:#echo $SHELLou#echo “$SHELL”

Produzindo o texto $SHELL:#echo ‘$SHELL’

Outro detalhe importante sobre o comando echo são as opções de posicionamento do texto, utilizadas em conjunto com o parâmetro -e do mesmo:

\\n : insere nova linha.\\t : insere tabulação horizontal (padrão para documentos de texto em

geral). \\v : insere tabulação vertical.\\b : insere um backspace.\\a : emite um sinal de “bip” do speaker.

Exemplos:

Exibir o texto de seguinte forma:HowToLPI#echo -e “How \\nTo \\nLPI”

Exibir o mesmo texto, só que com as linhas tabuladas horizontalmente:#echo -e “\\tHow \\n\\tTo\\n\\tLPI”

Page 6: Shell Script Tutorial

www.howtoday.com.br

Agora, o mesmo tabulado horizontalmente e verticalmente (espeçamento entre linhas):

#echo -e “\\v\\tHow \\n\\v\\tTo \\n\\v\\tLPI”

#readAtribui a uma variável o valor digitado pelo usuário.

Exemplos:

Lendo o valor da variável IP, que será lançado como 172.16.0.1 pelo usuário, e exportando a variável:

#read IP; export IP

Lendo, exportando e exibindo o valor da variável DSK_BKP com mensagem para o usuário:

#read -p “Digite o disco desejado para backup:” DSK_BKP#export DSK_BKP#echo $DSK_BKP

É lógico que o uso do read só é viável para um script, pois é a única forma de pedir para que o usuário lance um valor para uma variável.

Sub-ShellsQuando a saída desejada para STDOUT, STDIN ou STDERR é o resultado

de um comando, o ideal é utilizar um Sub-Shell, que é uma forma de um comando utilizar a saída de um outro comando ou de uma variável receber um resultado de comando. Um Sub-Shell pode ser representado por $(comando) ou por `comando`, como nos exemplos abaixo:

Fazendo backup de uma lista em um arquivo chaamado lista.txt:#tar -cjvf /backups/bkp-lista.tar.bz2 `cat lista.txt`

Execução de um scriptÉ importante que um script tenha permissão de execução para o usuário

que o quer utilizar, pois desta forma, ele pode ser executado se for informado o seu caminho completo ou se ele for copiado (ou se tiver um link) para um diretório do path do usuário é só executá-lo como um comando qualquer, apenas digitando o seu nome.

Outras formas de execução:#sh <script> (neste caso, o script não precisa ter permissão de

execução).#. <script> #./<script>#source <script>#bash <script>

Page 7: Shell Script Tutorial

www.howtoday.com.br

Exemplos:

Executando o script cria_users.sh criado acima como um comando no path do usuário:

#chmod +x ~/cria_users.sh && ln -s /root/cria_uses.sh /sbin/cria_users

#cria_users

Executando ~/cria_users.sh, que não está no path do usuário:#sh ~/cria_users.sh

Estruturas de análise lógica

As estruturas funcionam no Shell Script como na maioria das linguagens de programação, só que com sintaxes diferentes. É sempre recomendável para um programador Shell conheça pelo menos um pouco de algoritmos (o máximo possível), pois é preciso antes de implementar uma estrutura dessas, saber muito bem qual será o intuito, uma análise condicional, uma execução com “n” passos, uma estrutura de repetição ou uma análise de caso para um menu, por exemplo.

O uso de cada uma dessas estruturas é bem didático e bem simples, mesmo para o administrador de sistema Linux que nunca teve contato com lógica de programação.

Antes de conhecer cada uma das estruturas, é importante conhecer o comando abaixo:

testTesta arquivos, diretórios, números e strings (textos).

Testes numéricos:-eq : igual a.-lt : menor que.-le : menor ou igual.-gt : maior que.

Page 8: Shell Script Tutorial

www.howtoday.com.br

-ge : maior ou igual.-ne : diferente de.Testes em strings:= : igual a.!= : diferente de.-z : vazia.-n : não-vazia.Testes em aquivos:-d : é um diretório.-f : é um arquivo.-s : é um aquivo e não é vazio.-ef : é o mesmo arquivo.-nt : arquivo mais novo.-ot : arquivo mais velho.

Estrutura if (condicional)Analisa uma condição verdadeira e, para ela, executa uma série de

comandos. Também é possível adicionar uma condição para se teste for falso (else), mas esta não é imprescindível.

Sintaxe1:if <condição verdadeira>then <comandos>fiOnde fi finaliza a estrutura.

Sintaxe2:if <condição verdadeira>then <comandos>else <comandos>fi

Sintaxe3:if <condição verdadeira>then <comandos>else if <condição verdadeira>then <comandos>fifi

No modelo de sintaxe acima, temos uma estrutura if composta, onde a análise de condição falsa (else) pode receber uma outra estrutura if. Outro detalhe é que, como foram utilizadas 2 estruturas if, foram também finalizadas as duas com fi.

Exemplo1:

Page 9: Shell Script Tutorial

www.howtoday.com.br

No caso acima, o script acim testa a existência do arquivo /etc/nologin. Caso este exista, a mensagem ‘O login não será possível agora!!’ será exibida, caso contrário, a mensagem ‘Login liberado’ será exibida.

Exemplo2:

No caso acima, mais uma condição foi analisada: a de existir /etc/nologin, mas ele ser um diretório, e não um arquivo, neste caso, a mensagem ‘/etc/nologin é um diretório, não um arquivo’ será exibida.

Para estruturas if compostas com muitas condições, é utilizada a avaliação booleana ( E e OU). Em um exemplo abaixo, podemos testar a existência de /etc/network/interfaces e se este arquivo está vazio ou não antes de configurar a rede via script:

#!/bin/bashconfigura () {read -p “Qual a sua sala?” salaread -p “Qual a sua máquina?” maqecho -e “auto lo

Page 10: Shell Script Tutorial

www.howtoday.com.br

iface lo inet loopbackauto eth0iface eth0 inet staticaddress 10.$sala.1.$maqnetmask 255.255.255.0gateway 10.$sala.1.254” > /etc/network/interfaces ;;}

###A avaliação booleana ocorre abaixo, onde somente se o arquivo de configuração das interfaces de rede existir e não for vazio, os comandos serão executados:

if test -f /etc/network/interfaces && test -s /etc/network/interfacesthenecho ‘Existe um arquivo com este nome. Deseja sobrescrevê-lo(sim ou

não)?’read respfunction avalia {case $resp in sim|s|yes|y)configuranão|nao|n|no)exit 0 ;;*) read -p “Por favor, responda sim ou não. Pressione ENTER para voltar à

pergunta”avaliaesac}avaliaelse configurafi

#########FIM DO SCRIPT#############Para avaliação booleana, podem ser utilizados em conjunto com o

comando test:&& : apenas se todas as condições forem satisfeitas é que os comandos

são executados.|| : neste caso, basta que alguma das opções esteja correta para que os

comados sejam executados.

Estruturas while e untilEstras estruturas têm sintaxes diferentes, porém têm a mesma função: a

de executar tarefas em repetição (loop) mediante a um teste satisfeito.Estrutura while:while <teste verdadeiro>do <comandos>done

Estrutura until:

Page 11: Shell Script Tutorial

www.howtoday.com.br

until <teste falso>do <comandos>done

No caso de uma estrutura while, serão repetidos comandos enquanto aquele teste for verdadeiro, enquanto que na estrutura until é justamente o contrário: apenas quando o teste falso for satisfeito a repetição dos comandos vai parar de ser realizada.

Exemplos:

No caso acima, foi criado um “loop” de criação de diretórios onde, cada vez que este loop for executado, ele vai verificar se a variável qtd (quantidade de diretórios) ainda é maior que cont (um contador que foi criado para servir de referência), caso seja, cont vai ter o seu valor acrescido de 1 e vai servir de rótulo para a criação de um diretório com o nome dir-$cont, quando cont for igual à qtd, o loop acaba.

Neste script foram utilizados operadores matemáticos. Os operadores para Shell Script são:

+ : soma- : subtração.* : multiplicação./ : divisão.** : exponenciação. Para o caso de precisar fazer alguma operação aritmética, ela deve ser

deve ser realizada entre (( )) ou $(( )), como foi mostrado no exemplos acima.

Page 12: Shell Script Tutorial

www.howtoday.com.br

Neste caso acima, foi utilizada a estrutura de repetição until, que testou o valor da variável qtd até que ele fosse igual ao valor da variável cont, que, na verdade, agiu como uma constante neste script, já que o seu valor apenas serviu como parâmetro de comparação para a variável qtd, que permaneceu sendo subtraída de 1 a cada “loop” desses.

Estrutura for A estrutura for atribui para uma variável um valor de uma lista por vez.

Para cada passo dessa lista serão executados comandos que estiverem abaixo de “do”. Esta é uma ferramenta importantíssima para programas que precisam executar passos em sequência.

Sintaxe:for <variável> in <lista>do <comandos>done

Exemplo:

No programa acima, para cada diretório da lista extraída do arquivo /etc/passwd foi criado um arquivo de backup. Supondo que haja 20 usuários nesta lista, os comandos serão executados 20 vezes, portanto teremos 20 arquivos de backup, um para cada homedir de usuário, pois a cada passo desses, a variável home receberá um desses diretórios como valor.

O uso de for em scripts é útil também para criação de diretórios em demanda, utilizando o comando seq.

#seqExibe uma sequência numérica.

Exemplos:

Exibir de 1 até 100:#seq 100

Exibir de 10 até 100:#seq 10 100

Exibir de 10 até 100 com intervalo de 5:

Page 13: Shell Script Tutorial

www.howtoday.com.br

#seq 10 5 100

Exemplo de uso do seq na estrutura for:#vim ~/criadir_for.sh

Toda vez que é digitado um parâmetro para qualquer comando, este parâmetro é guardado na variável 1, por isso ela foi analisada sem ser solicitada pelo comando read.

No programa acima, a variável num, utilizada pela estrutura for, recebe cada um desses números que foram resultado do comando seq de cada vez e, para cada um deles, cria um diretório. Detalhe: tudo foi feito com apenas 4 linhas de script.

Vamos à execução do script (que vai criar 10 diretórios):#chmod +x ~/criadir_for.sh#ln -s ~/criadir_for.sh /sbin/criadir_for#criadir_for 10

Estrutura caseAnalisa se a variável se encontra em cada caso e, para cada um, executa

os comandos escolhidos pelo programador. Esta estrutura é muito útil na criação de programas com menu e também na criação de comandos que possuem argumentos.

Sintaxe:case <variável> in<opção1>) <comandos> ;;<opção2>) <comandos> ;;<opção3>) <comandos>esac

Em tese, este estrutura é uma ferramenta de substituição à estrutura if em análises muito grandes, como uma que precisasse de 10 condições, com o if este código ficaria enorme e, em qualquer linguagem de programação, é primordial que o programador prime pela boa organização de seu scripts, estruturas cada vez menores mas que tenham funcionalidade completa.Existe a necessidade de o programador providenciar que o script dele esteja bem documentado (com comentários e, se necessário, manuais), bem indentado e com as versões bem atualizadas, levando em consideração a freqüência com que elas são atualizadas para decidir se será uma versão com 2,3 ou até 4 dígitos.

Voltando à estrutura, cada opção do case deve ser separada da outra com ;; e o final da mesma é marcado pelo esac.

O tratamento de erros em uma estrutura case é feito por * em uma das opções significando “nenhuma das alternativas acima”.

Page 14: Shell Script Tutorial

www.howtoday.com.br

Vamos ver um exemplo de case usado para analisar um menu de opções em um programa para gerenciamento de pacotes:

A função menu, no caso deste script responde pelo menu e pela estrutura case inteira e, antes de ela ser executada, o sinal 2(sinal INT) foi capturado com o comando trap. Este comando insensibiliza uma linha de comandos a sinais em específico, neste caso a função não terá como ser interrompida com CTRL+C.

Quanto às opções, o | quer dizer “ou”, para o caso de o número ser digitado por extenso.

O uso do shiftQuando o usuário digita vários argumentos de um comando após o

mesmo, a mesma variável 1 tem que receber várias opções, uma de cada vez, para que as opções do comando sejam processadas corretamente. Pois então, o comando shift faz a função de fazer com que um valor atribuído à variável seja processado após o anterior já ter sido, fazendo com que a variável sempre receba valores em sequência.

A execução deste programa vai acarretar no backup de todos os diretórios dos usuários que forem digitados como argumentos do comando bkpusr (nome do porgrama), como no exemplo do backup dos diretórios pessoais dos usuários user1, operador e dba:

#bkpusr user1 operador dba