5automatizando Tarefas No Linux
5automatizando Tarefas No Linux
5automatizando Tarefas No Linux
PROPÓSITO
Conhecer ferramentas de automatização do Linux essenciais para tarefas do dia a dia em
servidores e estações de trabalho permitirá que tarefas rotineiras de administração e gerência
de sistemas Linux sejam realizadas de forma mais eficiente e eficaz.
PREPARAÇÃO
Para melhor aproveitamento do curso, recomendamos dispor de uma máquina Linux para
treinar com os exemplos apresentados. Caso não disponha de um computador com o Linux
instalado, há duas formas simples de obtê-lo, sem precisar reinstalar seu computador:
Mais simples e rápido: No Windows 10, instale o “Linux Subsystem” (da própria
Microsoft). Em seguida, na loja Microsoft Store, instale uma distribuição Linux. Sugestão:
Ubuntu Linux.
Mais avançado: Instale uma máquina virtual utilizando um Hypervisor como o Virtualbox
ou o Microsoft Hyper-V. Em seguida, baixe o CD de instalação de uma distribuição, à sua
escolha, e instale-o na máquina virtual.
OBJETIVOS
MÓDULO 1
MÓDULO 2
MÓDULO 3
MÓDULO 4
INTRODUÇÃO
Imagine que você é o administrador de um servidor Linux, responsável por um importante
serviço da empresa e, ao final de cada dia, um relatório sobre esse serviço deve ser enviado
para os gestores. Para emitir esse relatório diário, são necessários alguns comandos e a
contabilização de resultados. Em seguida, os números obtidos precisam ser digitados e
enviados por e-mail.
A situação acima é muito comum e faz parte do dia a dia de muitos administradores, com
tarefas rotineiras e repetitivas. Mas o cenário também descreve uma condição de baixa
eficiência do trabalho, já que exige um esforço manual para realizar uma tarefa recorrente.
Pense em todo o tempo acumulado, ao longo de meses ou anos, para a realização de uma
única e específica tarefa, repetidamente. Por fim, a pessoa responsável por essa tarefa deverá
estar disponível nos dias e horários determinados, e sua ausência precisará ser suprida por
outra pessoa, ou a tarefa não será realizada.
MÓDULO 1
De simples configuração, o CRON permite determinar dias e horários em que comandos serão
executados, de forma automática e sem a intervenção de usuários.
FERRAMENTA MULTIUSUÁRIO
É importante entender que o CRON é uma ferramenta multiusuário. Na prática, isso significa
que cada usuário no sistema operacional poderá ter sua configuração própria e independente
dos demais usuários.
No CRON, os processos são sempre executados pelo usuário a quem pertence a configuração.
Por exemplo, considere duas configurações de CRON, aqui representadas com palavras:
EXEMPLO
– Usuário ‘root’
- Usuário ‘bob’
ATENÇÃO
$ crontab -e
Observação:
Ao usar o comando ‘crontab’ pela primeira vez, poderá ser apresentada uma opção para
escolha do editor de texto.
DICA
Escolha o editor com que se sinta mais confortável. Se não tiver certeza, prefira um editor mais
simples como o ‘nano’.
$ crontab -e
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Quando terminar de editar o CRONTAB, você deverá salvá-lo. Se for o editor ‘nano’, use a
combinação de teclas Crtl-X.
Ao abrir o editor, o CRONTAB poderá estar preenchido com diversas informações e instruções
que as distribuições Linux incluem para auxiliar os usuários.
REGRAS E FORMATOS DO CRONTAB
Todas as linhas começadas com ‘#’ são tratadas como comentários e, portanto, ignoradas
pelo CRON. Em geral, os editores mostrarão essas linhas com cores destacadas para
facilitar a visualização.
Cada tarefa será configurada em uma (e somente uma) linha, que deverá conter os
campos requeridos pelo CRON.
O sexto campo e os demais representam o comando que será executado pelo CRON, no
dia e horário estabelecido.
MINUTO
HORA
DIA DO MÊS
Número de 1 a 31, representando o dia do mês.
MÊS
DIA DA SEMANA
0 → domingo
1 → segunda-feira
2 → terça-feira...
O dia da semana costuma causar confusão entre nativos da língua portuguesa, pois nesse
idioma alguns dias da semana são numerais (segunda, terça, quarta...). Esteja atento para
isso.
O CRON também admite o uso da máscara ‘*’ para representar ‘qualquer valor’.
Fonte: O autor
30 17 10 * * /bin/comando
30 17 * 12 * /bin/comando
30 17 * * 5 /bin/comando
30 17 10 3 * /bin/comando
30 17 * 3 1 /bin/comando
O CRON também permite incluir mais de um valor por campo e criar agendamentos
sofisticados.
Valores separados por vírgula: A execução será disparada quando qualquer um dos
valores for atendido.
Valores separados por traço: Indica intervalo, e o comando será executado quando
qualquer um dos valores no intervalo for atendido.
0,15,30,45 * * * * /bin/comando
Nesse exemplo, o comando será executado nos minutos 0, 15, 30 e 45, todas as horas do dia,
todos os dias.
O comando será executado nos horários do exemplo acima, porém somente de segunda a
sexta-feira (1-5).
O comando será executado nos minutos 0 e 30, das horas 8 a 17 e somente de segunda a
sexta-feira. Ex: 8h, 8h30, 9h, 9h30 .... 16h30, 17h e 17h30.
Também é possível definir o período entre intervalos usando o caractere ‘/’. Por exemplo:
0 */2 * * * /bin/comando
O comando será executado no minuto 0 a cada duas horas (/2): 0h, 2h, 4h, 6h ... 22h.
0/10 * * * * /bin/comando
O comando ‘tar -cfz /tmp/backup.tar.gz /home/bob’ cria um arquivo TAR comprimido, com todo
o conteúdo do diretório /home/bob. O nome desse arquivo será backup.tar.gz e estará dento do
diretório /tmp. É um tipo de comando muito usado para fazer o backup de diretórios de usuários
ou de aplicações em geral.
Se quisermos automatizar essa tarefa para que seja executada todos os dias às 20h, devemos
incluir a linha abaixo no CRONTAB:
Lembre-se: o CRON é um serviço multiusuário. O usuário que for executar o comando ‘tar’
deverá ter, ao mesmo tempo, permissão para ler o conteúdo do diretório de origem (/home/bob)
e permissão para escrever no diretório de destino (/tmp).
ATENÇÃO
Importante: Não use o comando ‘sudo’ dentro do CRONTAB. O comando ‘sudo’ é interativo e
requer a digitação de senha, o que não será possível enquanto estiver sendo executado pelo
CRON. Em vez de usar o ‘sudo’, configure o comando diretamente no CRONTAB do usuário
‘root’.
EXEMPLO
Alguns exemplos:
O arquivo usado é o /etc/crontab. Como ele define uma configuração para todo o sistema, seu
formato exige um campo a mais em cada linha, que é a indicação do usuário que executará
cada comando.
30 10 * * * root /bin/comando
No exemplo acima, a indicação de que o CRON deverá executar o comando como o usuário
‘root’.
As principais distribuições Linux trazem a configuração global com uma organização prática, já
que rotinas poderão ser incluídas e excluídas à medida que serviços são instalados e
desinstalados no servidor.
Para que o arquivo /etc/crontab não precise ser alterado, é costume criar diretórios para as
rotinas diárias, semanais e mensais. Em cada diretório serão criados programas (scripts) para
cada uma das tarefas definidas.
Para exercitar: Procure esses diretórios na sua máquina Linux e veja os seus conteúdos.
Assista ao vídeo abaixo e descubra, na prática, como agendar tarefas no Linux:
VERIFICANDO O APRENDIZADO
20 10 * * 0 /OPT/RELATORIO
0 15 1 * * SUDO /ROOT/APAGAR_ARQUIVOS_ANTIGOS
B) O comando ‘sudo’ não deve ser usado no CRONTAB. No lugar dele, a tarefa deve ser
configurada no CRONTAB do usuário ‘root’.
C) A configuração define que o comando deve ser executado no dia 15 de cada mês, mas
somente se for um domingo.
D) A configuração possui um erro, pois indica o mês de número 15, quando o valor deve estar
entre 1 e 12, obrigatoriamente.
GABARITO
20 10 * * 0 /opt/relatorio
A configuração da tarefa no CRONTAB define que ela deverá ser executada às 10h20, todos
os domingos. A primeira coluna indica o minuto: 20. A segunda coluna indica a hora: 10. As
terceira e quarta colunas indicam o dia do mês e o mês: o caractere ‘*’ significa ‘todos os
valores possíveis’. A quinta coluna indica o dia da semana: O valor ‘0’ se refere ao domingo.
2. O usuário ‘luiz’ configurou seu CRONTAB para executar um SCRIPT, porém verificou
que ele não está sendo executado como esperado. A linha configurada no CRONTAB é:
0 15 1 * * sudo /root/apagar_arquivos_antigos
Por se tratar de um comando interativo, o ‘sudo’ não deve ser usado no CRON. Quando o
‘sudo’ é executado pela primeira vez, ele solicita que o usuário digite a sua senha, o que não
vai acontecer quando estiver sendo executado a partir do CRON. Portanto, o SCRIPT ficará
aguardando indefinidamente por uma informação que não poderá ser fornecida.
MÓDULO 2
COMENTÁRIO
Por serem lidos e interpretados diretamente pelo SHELL, não há necessidade de um processo
de compilação como em diversas linguagens de programação. Após escritos, os arquivos
contendo os SCRIPTS podem ser executados imediatamente.
Os SCRIPTS mais simples são aqueles que simplesmente executam diversos comandos em
sequência, economizando nosso tempo. Os mais complexos podem analisar os resultados dos
comandos e tomar decisões para os comandos seguintes, executando a tarefa com segurança,
integridade e eficiência.
O INTERPRETADOR DE SHELL
Existem diversos interpretadores disponíveis para o Linux, e as sintaxes para SCRIPTS variam
entre eles. Atualmente, as principais distribuições adotam o interpretador BASH como o
padrão, portanto vamos utilizá-lo como referência nesse curso.
A PALAVRA MÁGICA QUE IDENTIFICA UM
SCRIPT
O Linux nos permite executar um SCRIPT da mesma forma que executamos um comando ou
programa qualquer, mas isso tem uma implicação: Precisamos informar que o conteúdo
daquele arquivo é um SCRIPT e não um arquivo qualquer.
Para isso, todo SCRIPT deve ser iniciado com uma palavra mágica, composta por dois
caracteres ‘#!’ seguidos do caminho para o interpretador de SHELL.
Fonte:Shutterstock
#!/bin/bash
Neste exemplo estamos declarando que o arquivo é um SCRIPT e deverá ser interpretado pelo
BASH, sendo /bin/bash o caminho completo para esse programa interpretador.
$ nano script1
A palavra mágica.
#!/bin/bash
date
Já percebemos que esse exemplo é um SCRIPT muito simples, sem grande utilidade, já que
terá o mesmo efeito de simplesmente digitarmos o comando ‘date’. Mas o objetivo agora é
rodar o nosso primeiro SCRIPT.
Salve o arquivo e saia do editor. Se estiver usando o ‘nano’, use Ctrl-X, confirme que deseja
salvar o arquivo e escolha o nome (‘script1’).
4
Se agora usarmos o comando ‘ls’ para ver o conteúdo do diretório, encontraremos o nosso
‘script1’ entre os arquivos. Porém, se tentarmos digitar ‘script1’ no PROMPT, receberemos um
erro do tipo “comando não encontrado”.
A primeira delas é que criamos um arquivo texto, mas em momento algum autorizamos que ele
seja executado, e essa é uma característica de segurança importante do Linux.
Não basta criar um arquivo texto para que ele se comporte como um programa, é necessário
dar permissão de execução para ele.
Se tentarmos executar o comando agora, ainda receberemos um erro, o que nos leva à
segunda questão, outro mecanismo de proteção do Linux: Apenas programas em alguns
diretórios do sistema podem ser executados sem a necessidade de indicar o seu
caminho.
Como o SCRIPT foi criado no HOME e esse não é um dos diretórios permitidos, precisaremos
indicar o caminho, que pode ser utilizando o caminho absoluto ou relativo.
Para executar o ‘script1’ que está no diretório atual, vamos empregar o caminho relativo, com o
comando abaixo:
./script1
$ ./script1
VOCÊ SABIA
As linhas sem conteúdo e as iniciadas com ‘#’ são ignoradas pelo interpretador.
As linhas iniciadas com ‘#’ podem ser usadas para comentários, observações e instruções
sobre o SCRIPT.
Não confunda com a palavra mágica na primeira linha: Ela começa com ‘#’ e é
importante.
Nesse exemplo, vamos mudar a saída para indicar somente a hora e com um texto mais
amigável. Desejamos que a saída seja assim quando o SCRIPT for executado:
$ date +%H:%M
Saiba Mais
SAIBA MAIS
(%H será substituído pela hora e %M pelo minuto. Para mais formatos, consulte a
MANPAGE do comando ‘date’).
O texto pode ser inserido usando-se o comando ‘echo’. Vamos mudar o SCRIPT para:
#!/bin/bash
date +%H:%M
O comando ‘echo’ envia para a saída padrão (stdout) o texto passado como parâmetro.
$ ./script1
Hora certa
12:30
As informações que desejamos já estão presentes, porém em linhas diferentes. Isso ocorre
porque o comando ‘echo’ insere uma quebra de linha após o texto. É possível inibir a quebra
de linha passando o parâmetro ‘-n’ para o comando ‘echo’. Porém, vamos adaptar o SCRIPT
colocando tudo no mesmo ‘echo’.
#!/bin/bash
Quando colocamos o comando entre ‘$(‘ e ‘)’ estamos dizendo ao ‘echo’: Execute esse
comando e envie o resultado junto ao texto para a saída. Então, ao executarmos o script,
teremos:
$ ./script1
#!/bin/bash
$ ./script1
Repare nesse último exemplo que o comando ‘date’ foi executado duas vezes dentro do ‘echo’.
#!/bin/bash
$ ./script1
Data: 15/09/2020
Hora: 16:44
#!/bin/bash
date +%T
sleep 1
date +%T
sleep 2
date +%T
sleep 3
date +%T
No ‘script2’ o comando ‘date’ é executado 4 vezes. Entre eles foi usado o comando ‘sleep’ com
diferentes tempos. O número passado como parâmetro ao ‘sleep’ corresponde ao tempo, em
segundos, de pausa.
Ao executá-lo, obtemos:
$ ./script2
13:05:29
13:05:30
13:05:32
13:05:35
Fonte: O Autor
Em muitos casos, pode ser interessante aguardar uma interação do usuário. O comando ‘read’
suspende a execução do SCRIPT até que o usuário tecle ENTER.
#!/bin/bash
date +%T
read
date +%T
read
date +%T
read
date +%T
O SCRIPT aguardará que o usuário digite ENTER após executar cada comando ‘date’.
Comparando-se as horas, será possível saber quanto tempo o SCRIPT aguardou por cada
interação do usuário.
$ ./script2
13:09:12
13:09:14
13:09:16
13:09:18
As linhas em branco foram inseridas pela resposta do comando ‘read’ ao ENTER do usuário.
DICA
Experimente incluir o parâmetro ‘-s’ nos comandos ‘read’ para que as linhas em branco não
apareçam.
#!/bin/bash
clear
date +%T
read
date +%T
read
date +%T
read
date +%T
O resultado será igual ao anterior, porém o terminal estará limpo e a resposta começará na
primeira linha.
COMENTÁRIO
O valor de retorno pode ser de 0 a 255, e a regra geral é de que um valor de retorno 0 indica
execução com sucesso. Os demais valores, de 1 a 255, podem ser usados para indicar o tipo
de erro durante a execução.
exit 1
Quando o ‘exit’ for executado, o SCRIPT será imediatamente encerrado e com valor de retorno
igual a ‘1’.
Se o comando ‘exit’ for executado sem o parâmetro de valor, ele retornará o resultado do último
comando no SCRIPT. Isso também vale para um SCRIPT que não termina através do comando
‘exit’.
No vídeo a seguir, você encontrará comandos do Linux diferentes dos apresentados no tema,
passando por todos os passos, desde a criação do script, alteração das permissões e a
execução do script.
VERIFICANDO O APRENDIZADO
#!/BIN/BASH
#ECHO “CODIGO 1”
#SHOW “CODIGO 2”
EXIT 0
C) O SCRIPT não pode ser executado, pois a declaração inicial (!/bin/bash) está precedida
pelo caractere ‘#’.
D) Ao término da execução do SCRIPT, nenhuma informação terá sido enviada para o terminal.
CLEAR
READ
CD /TMP
...
GABARITO
#!/bin/bash
#echo “Codigo 1”
#show “Codigo 2”
exit 0
clear
read
cd /tmp
...
O comando ‘read’, executado como no SCRIPT acima, interrompe a execução até que o
usuário digite a tecla ENTER. O comando ‘clear’ apaga as informações que eram exibidas no
terminal, deixando a tela “limpa”. O comando ‘cd /tmp’ muda o diretório atual.
MÓDULO 3
COMENTÁRIO
Utilizando variáveis podemos compartilhar dados entre vários comandos e tomar decisões para
desviar o fluxo de execução do SCRIPT.
NOME
O nome de uma variável é a chave pela qual faremos referência a ela.
VALOR
O valor é a informação armazenada.
VAR=1
Nesse exemplo, declaramos uma variável com o nome “VAR” e a ela foi atribuído o valor “1”.
Se a variável VAR já existir, o valor anterior será perdido e substituído pelo novo.
ATENÇÃO
Na atribuição acima não deve haver espaços antes ou depois do sinal de igualdade, o que faria
o terminal interpretar como a tentativa de executar o comando ‘VAR’ ou ‘VAR=’
VAR=”Terminal do Linux”
REFERENCIANDO VARIÁVEIS
Para fazer referência a uma variável, e obter o seu conteúdo, é necessário usar o símbolo $ à
esquerda do nome. Se a variável se chama VAR, faremos referência a ela como $VAR.
VAR=”Terminal do Linux”
echo “$VAR”
A saída do comando ‘echo’ será a frase “Terminal do Linux”. O ‘echo’ substituiu a referência
$VAR pelo conteúdo da variável.
ATENÇÃO 1
ATENÇÃO 1
A variável só é utilizada sem o prefixo $ quando estamos atribuindo valor a ela. Para
fazer referência, o $ sempre é necessário.
ATENÇÃO 2
ATENÇÃO 2
No terminal BASH, ao contrário da maioria das linguagens de programação, as variáveis
não possuem tipo. Portanto, a interpretação do conteúdo como número ou texto vai
depender do contexto da operação que está sendo realizada.
No exemplo abaixo, simulamos um SCRIPT cuja execução é demorada. Para que o usuário
saiba quanto tempo a execução demorou, esse SCRIPT apresentará no final os horários em
que começou e o atual.
#!/bin/bash
INICIO=$(date +%T)
sleep 5
exit 0
COMENTÁRIO
Repare na segunda linha que o comando ‘date’ é executado, retornando a hora naquele
momento, que será armazenada na variável INICIO. O comando ‘sleep 5’ simula uma tarefa
demorada, aqui com 5 segundos de duração.
Ao término da execução teremos os dois horários, o que nos permitirá saber quanto tempo o
SCRIPT levou para executar:
./script3>
ATENÇÃO
Suponha um SCRIPT sendo executado com o comando abaixo, onde foram passados 4
parâmetros (lembre-se: Os parâmetros são separados pelo espaço).
Cada um dos parâmetros pode ser lido pelo SCRIPT consultando as variáveis $1, $2, $3 e $4,
respectivamente. A variável $0 é o nome do próprio SCRIPT que foi executado.
Considere o ‘script4’:
#!/bin/bash
Esse SCRIPT irá buscar os 4 primeiros parâmetros e os exibirá. Os parâmetros que não forem
preenchidos serão vistos como vazio pelo SCRIPT.
Ao executar o SCRIPT, teremos a saída (não esqueça de conceder permissão de execução):
Parametro 1: valor1
Parametro 2: valor2
Parametro 3: valor3
Parametro 4: valor4
ATENÇÃO
O OPERADOR LÓGICO IF
Assim como quase todas as linguagens de programação, o BASH também permite
comparações por meio do comando ‘if’.
O comando recebe uma expressão para ser avaliada, e seu retorno dependerá do resultado da
avaliação.
if [ CONDIÇÃO ]
then
# Alguma tarefa #
fi
VERDADEIRO
Se o resultado for verdadeiro, ele executará o código entre ‘then’ e ‘fi’, nesse exemplo
representado pela frase “# Alguma tarefa #”.
FALSO
Se o resultado for falso, o fluxo da execução é desviado para depois do ‘fi’, portanto os
comandos em “# Alguma tarefa #” não são executados.
O operador ‘if’ também permite o uso da declaração ‘else’, que será executada sempre que o
resultado da condição for falso.
if [ CONDIÇÃO ]
then
else
fi
COMPARADORES NUMÉRICOS
Observe os comparadores numéricos
Resulta verdadeiro se o valor da variável $A for maior que o valor da variável $B.
Resulta verdadeiro se o valor da variável $A for maior que o valor da variável $B ou igual.
MENOR QUE ( -LT → LESS THAN )
if [[ “$A” -lt “$B” ]]
Resulta verdadeiro se o valor da variável $A for menor que o valor da variável $B.
Resulta verdadeiro se o valor da variável $A for menor que o valor da variável $B ou igual.
Para exemplificar, considere esse ‘script5’ que recebe dois valores como parâmetros e realiza
uma série de comparações:
#!/bin/bash
A=$1
B=$2
then
fi
then
fi
then
fi
then
fi
O primeiro parâmetro ($1) é atribuído como o valor da variável $A, e o segundo como o valor
da variável $B.
Ao executarmos, a saída dependerá dos valores passados:
$ ./script5 10 5
A e B são diferentes
A é maior que B
$ ./script5 10 20
A e B são diferentes
A é menor que B
$ ./script5 10 10
A e B são iguais
COMPARADORES DE CADEIAS DE
CARACTERES (STRINGS)
Observe agora os comparadores de cadeias de caracteres:
IGUALDADE
if [[ “$A” = “$B” ]]
DIFERENTE
if [[ “$A” != “$B” ]]
Resulta verdadeiro se o valor (texto) da variável $A tiver zero caracteres (tamanho zero).
Resulta verdadeiro se o valor (texto) da variável $A tiver tamanho maior do que zero.
COMENTÁRIO
O SCRIPT que desenvolvemos no exemplo anterior possui uma falha: Se for executado sem
parâmetros vai retornar erro, pois tentará comparar valores ($1 e $2) que não existem.
Esse problema pode ser facilmente resolvido incluindo-se um teste de validade dos parâmetros
no início da execução.
#!/bin/bash
A=$1
B=$2
if [[ -n "$A" ]]
then
else
exit 1
fi
if [[ -n "$B" ]]
then
else
exit 1
fi
then
fi
then
f1
then
fi
then
fi
exit 0
Se tentarmos executar o SCRIPT sem preencher ambos os parâmetros, o erro do usuário será
detectado e indicado.
$ ./script5
$ ./script5 22
O comando ‘read’, que usamos no módulo anterior para aguardar uma interação do usuário,
também pode ser usado para receber um valor e atribuí-lo a uma variável.
$ read A
Irá aguardar o usuário digitar alguma informação, e terminar com ENTER. A informação
digitada será atribuída à variável A.
$ read A
$ echo “$A”
Mensagem
Vamos criar uma versão interativa do exemplo que executamos anteriormente. Nessa versão,
apenas o começo do SCRIPT será modificado – em vez de receber A e B por parâmetros, eles
serão obtidos do usuário pelo comando ‘read’.
#!/bin/bash
# O parâmetro '-n' no echo faz com que ele não insira uma quebra de linha apos o texto
read A
read B
if [[ -n "$A" ]]
then
else
exit 1
fi
if [[ -n "$B" ]]
then
else
exit 1
fi
then
fi
then
fi
then
fi
then
fi
exit 0
Como um primeiro exemplo, observe o ‘script6’ que solicitará dois valores e retornará a soma
deles:
#!/bin/bash
# variáveis A e B
read A
read B
(( C=A+B ))
# Exibe o resultado
exit 0
$ ./script6
O resultado de A+B = 27
O resultado de A+B = 27
ATENÇÃO
O cálculo foi realizado de duas formas. Na primeira, o resultado foi atribuído a uma variável (C).
Na segunda forma, o cálculo foi feito diretamente a partir do comando ‘echo’.
INCREMENTANDO VARIÁVEIS
Em estruturas de repetição, precisamos de variáveis auxiliares, que são constantemente
incrementadas. O incremento de uma variável X pode ser feito com:
(( X++ ))
Exemplo:
$ X=1
$ echo $X
$ (( X++ ))
$ echo $X
ATENÇÃO
Um comando que pode nos auxiliar é o ‘bc’ (consulte a MANPAGE para maiores informações).
No exemplo abaixo, o comando é invocado recebendo de um ‘echo’ a expressão para ser
calculada.
9.66666
A expressão tem duas partes, separadas por ponto e vírgula. A primeira parte (scale=5) define
quantas casas decimais deverá ter a resposta. A segunda parte é o cálculo, nesse caso 29
dividido por 3.
Considere o ‘script7’ abaixo, que pede ao usuário três números (A, B e C) e calcula sua média.
#!/bin/bash
read A
read B
read C
exit 0
Ao executar o SCRIPT:
$ ./script7
Repare que o comando ‘bc’ realizou o cálculo utilizando ponto flutuante, sem perder as casas
decimais no resultado.
Ao assistir ao vídeo a seguir, você observará scripts com empregos de variáveis e estruturas
de decisão, além do uso do switch case como alternativa ao uso do IF.
VERIFICANDO O APRENDIZADO
IF [[ $1 -EQ 0 ]]
THEN
ELSE
FI
EXIT 0
$ RESPOSTA 5 6 7
A) Resposta: 1
B) Resposta: 5
C) Resposta: 6
D) Resposta: 7
#!/BIN/BASH
READ A
READ B
IF [[ $A -GT $B ]]
THEN
ECHO $((A+B))
FI
EXIT 0
A) Se a soma dos dois valores, A e B, for maior do que zero, o SCRIPT termina imediatamente.
B) Se o valor de A for maior que o valor de B, o SCRIPT retorna a soma dos dois.
D) Se os valores de A e B forem iguais, o SCRIPT termina com código de retorno zero, que
representa execução sem erros.
GABARITO
#!/bin/bash
if [[ $1 -eq 0 ]]
then
else
fi
exit 0
$ resposta 5 6 7
No início do SCRIPT há um operador ‘if’ comparando o valor de $1 com ‘0’ (zero). Como $1
não atende a essa comparação (pois $1 é 5), o trecho abaixo do ‘else’ será executado.
O
comando ‘echo “Resposta: $2”’ faz com que seja exibida a palavra “Resposta: “ e o $2 é
substituído pelo segundo parâmetro recebido pelo SCRIPT, neste exemplo, o ‘6’. Portanto, a
saída do SCRIPT será: “Resposta: 6”.
2. Considere o SCRIPT abaixo que, ao ser executado, pede ao usuário que digite dois
valores, A e B.
#!/bin/bash
read A
read B
if [[ $A -gt $B ]]
then
echo $((A+B))
fi
exit 0
O comparador ‘-gt’ usado no ‘if’ retorna verdadeiro se o valor de A for maior que o valor de B.
Nesse caso, serão executados os comandos abaixo do ‘then’.
MÓDULO 4
Toda programação em LOOP deve definir uma condição para saída, ou seja, o critério para
determinar o encerramento da execução, do contrário o LOOP será executado indefinidamente.
Essa condição é chamada de LOOP infinito e, quase sempre, é indesejada.
Neste módulo, veremos duas estruturas para realizar LOOPS: ‘while’ e ‘for’.
while [ CONDIÇÃO ]
do
comando1
comando2
...
done
1
Inicialmente, a condição é avaliada. Se for atendida, todos os comandos entre ‘do’ e ‘done’ são
executados.
2
Então, a condição é avaliada novamente e, se ainda for atendida, os comandos serão
novamente executados.
3
Quando a condição não for atendida, o LOOP é interrompido e o SCRIPT segue executando os
comandos após o ‘done’.
#!/bin/bash
# a visualização
clear
read num
i=1
do
(( i++ ))
# Aguarda um segundo
sleep 1
done
# estiver encerrado.
exit 0
Ao executar o SCRIPT:
$ ./script8
Digite um número: 10
Contando... 1
Contando... 2
Contando... 3
Contando... 4
Contando... 5
Contando... 6
Contando... 7
Contando... 8
Contando... 9
Contando... 10
INTERFERINDO NA EXECUÇÃO DE UM
LOOP
Os comandos ‘break’ e ‘continue’ permitem interferir na execução de um LOOP:
BREAK
O comando ‘break’ força a interrupção imediata do LOOP, mesmo que a condição tenha sido
satisfeita.
CONTINUE
Já o comando ‘continue’ força uma nova iteração do LOOP, ou seja, retorna a execução para o
começo do LOOP.
Para tal, usaremos um ‘if’ a cada iteração comparando o valor do segundo atual com o “00”.
#!/bin/bash
# a visualização
clear
read num
i=1
do
# Exibe o contador $i
echo "Contando... $i"
(( i++ ))
then
fi
# Aguarda um segundo
sleep 1
done
# estiver encerrado.
exit 0
Ao executar o SCRIPT, podemos ver a interrupção forçada pela condição dos segundos no
relógio do computador.
$ ./script9
Digite um número: 60
Contando... 1
Contando... 2
Contando... 3
Contando... 4
Contando... 5
Contando... 6
Contando... 7
Contando... 8
Contando... 9
Contando... 10
Se fosse digitado um valor abaixo de 60, haveria uma chance do SCRIPT encerrar sua
execução normalmente, antes do ponteiro dos segundos passar pelo ‘0’.
DICA
Experimente trocar o comando ‘break’ por ‘continue’. Nesse caso, quando o ponteiro dos
segundos for zero, uma nova iteração do LOOP será iniciada, sem a execução da espera pelo
comando ‘sleep’.
#!/bin/bash
for numero in 10 11 15 20 29 36 41 45
do
done
exit 0
$ ./script10
Número: 10
Número: 11
Número: 15
Número: 20
Número: 29
Número: 36
Número: 41
Número: 45
#!/bin/bash
contador=1
for arquivo in *
do
(( contador++ ))
done
Nesse exemplo, o ‘for’ recebe um ‘*’ como lista. Esse caractere é uma máscara que será
substituída por uma lista com todas as entradas (arquivos e diretórios) existentes no diretório
atual. Adicionalmente, foi incluída uma variável ‘contador’ para contar a quantidade de arquivos
à medida que são exibidos.
$ ./script11
SAIBA MAIS
Utilizando os conceitos deste curso, podemos criar SCRIPTS com lógicas avançadas para
atender às nossas necessidades.
Vamos propor um exemplo de SCRIPT para aplicarmos os conceitos que aprendemos até aqui:
Exemplo de SCRIPT: Levantamento de espaço ocupado
OBTENDO UMA VARIÁVEL A PARTIR DE
UM ARQUIVO TEXTO
O SCRIPT de Levantamento de espaço ocupado, visto anteriormente, tem uma característica
que pode ser considerada como inconveniente por muitos administradores:
Será necessário que um usuário possua permissão de escrita para modificar o SCRIPT.
Uma forma de resolver o problema é separar essa informação, a lista de diretórios, do SCRIPT.
COMENTÁRIO
Para fazer isso, primeiro devemos criar um arquivo para a lista de diretórios. Cada diretório
deve estar em uma linha do arquivo. Por exemplo, foi o criado o arquivo ‘lista_diretorios’ com o
conteúdo abaixo:
/etc
/home
/lib
/usr/bin
/usr/lib
/usr/local
/usr/sbin
/var/lib
/var/log
/var/spool
/tmp
DIRETORIOS=$(< lista_diretorios)
Repare que foi utilizado o redirecionador de entrada ‘<’, para leitura do arquivo ‘lista_diretórios’.
CONSIDERAÇÕES AO EXECUTAR UM
SCRIPT A PARTIR DO CRON
COMENTÁRIO
É muito provável que você desenvolva SCRIPTS para execução automática, através de
serviços como o CRON. Como se trata de uma execução não assistida, o seu SCRIPT não
poderá depender de um terminal.
Sempre considere:
Comandos e dados que mudam a cada execução devem ser passados por meio de
arquivos, ainda que temporários, e parâmetros de execução.
Caso seu SCRIPT não envie diretamente para um arquivo, e não seja desejável adaptá-
lo, você pode utilizar um redirecionador (> ou >>) na execução, diretamente no
CRONTAB.
Por exemplo:
O CRON pode ser configurado para enviar as saídas de um comando por mensagem
para a caixa postal local do usuário. Porém, se considerar que essas informações são
importantes e não podem ser perdidas, prefira o arquivo texto de LOG.
SAIBA MAIS
Um recurso muito útil para quem escreve SCRIPTS são as expressões regulares (regular
expressions, ou simplesmente, regex). Com elas podemos realizar comparações complexas e
transformações de dados.
Em diversos exemplos, desenvolvemos SCRIPTS que pediam ao usuário para digitar valores
ou textos, e vimos como fazer uma validação simples dessas variáveis.
E se quisermos, por exemplo, garantir que o usuário digitou um número de, exatamente, 3
dígitos? Observe o SCRIPT abaixo:
#!/bin/bash
read numero
if [[ $numero =~ ^[0-9]{3}$ ]]
then
echo "OK"
else
fi
[0-9]
{3}
Ou seja, a comparação só será válida se a cadeia for composta por, exatamente, 3 caracteres
de 0 a 9.
Ao assistir ao vídeo a seguir, você observará scripts com emprego das estruturas de repetição,
combinadas com os recursos apresentados nos módulos anteriores e exemplos de casos
práticos para a administração de servidores Linux.
VERIFICANDO O APRENDIZADO
1. ANALISE O SCRIPT ABAIXO E ESCOLHA A OPÇÃO QUE DESCREVE
CORRETAMENTE O SEU FUNCIONAMENTO.
#!/BIN/BASH
I=0
WHILE [[ $I -NE 10 ]]
DO
READ X
IF [[ $X -EQ 1 ]]
THEN
BREAK
FI
(( I++ ))
DONE
EXIT 0
B) O SCRIPT pede que o usuário digite 10 valores e encerra a execução após o último.
C) O SCRIPT fica em LOOP indefinidamente até que o usuário digite o valor ‘10’.
A="1 2 3 4 5"
B) while [[ $A -ne 0 ]]
C) for valor in $A
D) if [[ $A ]]
GABARITO
#!/bin/bash
i=0
while [[ $i -ne 10 ]]
do
read X
if [[ $X -eq 1 ]]
then
break
fi
(( i++ ))
done
exit 0
O ‘while’ estabelece um LOOP que não se encerrará até que a variável $i tenha o valor 10.
Dentro do LOOP, vemos que a variável $i é incrementada em uma unidade a cada iteração.
Portanto, o LOOP executará 10 vezes, se não for interrompido antes.
Dentro do LOOP, o comando ‘read’ recebe um valor, que será comparado, pelo ‘if’, com o valor
‘1’. Se for igual, o LOOP é imediatamente encerrado.
Portanto, ao executar o SCRIPT, ele inicia
um LOOP e a cada iteração receberá um valor digitado pelo usuário. Se esse valor for ‘1’, o
LOOP se encerra imediatamente. Após pedir a digitação pela 10ª vez, o SCRIPT se encerra
independentemente dos valores digitados.
A="1 2 3 4 5"
A estrutura de repetição que executa uma iteração de LOOP para cada valor na variável
A é:
O operador ‘for’ percorrerá o conteúdo da variável $A, obtendo um valor por vez e o atribuindo
a uma variável temporária. Para o comando ‘for valor in $A’, essa variável temporária será
$valor.
CONCLUSÃO
CONSIDERAÇÕES FINAIS
Ao longo deste tema, conhecemos ferramentas muito importantes para a administração de
servidores e estações baseadas no sistema operacional Linux.
A possibilidade de criar SCRIPTS para a execução de tarefas nos permite definir algoritmos
sofisticados para tratar praticamente qualquer cenário que nosso ambiente nos apresente.
Com o CRON, podemos agendar a execução dessas tarefas e tornar nossa administração
automatizada e independente da interação de usuários.
Para aqueles que ainda não têm grande intimidade com programação, deixo como sugestão
investir um pouco de tempo no estudo de algoritmos. A capacidade de abstrair problemas reais
em passos lógicos e programá-los nos oferece grande versatilidade e eficiência, essenciais
para qualquer administrador de sistemas.
AVALIAÇÃO DO TEMA:
REFERÊNCIAS
MAXWELL, S. Administração de sistemas Unix. 1. ed. Rio de Janeiro: Ciência Moderna,
2003.
PETERSEN, R. Ubuntu 18.04 LTS Server: Administration and Reference. 1. ed. Surfing Turtle
Press, 2018.
UBUNTU. Ubuntu Server Guide. Consultado em meio eletrônico em: 19 out. 2020.
EXPLORE+
Para saber mais sobre os assuntos tratados neste tema, leia:
CURRÍCULO LATTES