Shell Script – Estrutura de repetição e arrays

Estruturas de repetição em shell script, como em demais linguagens aqui teremos o for, while e o until e irei aproveitar o engajado para passar arrays em Shell Script que ficara perfeito com estrutura de repetição.

FOR

Estrutura bem parecida com a de outras linguagens porém com varias maneiras de implementar, podemos na própria estrutura For definir o numero de elementos “1 2 3 4 5”, ou uma sequencia “seq 10” e ele irá repetir até o fim desta condição.

Exemplo:

WHILE

Muito parecido com o For, pode praticamente fazer a mesma coisa porém uma definição mais claro entre os dois é que o For irá iniciar em um valor e irá parar quando chegar em outro definido, o while também pode trabalhar assim além de continuar no laço enquanto a condição for verdadeira.

Exemplo:

UNTIL

Imagine o oposto do While, pois é esse é o until, no while enquanto é executado o laço enquanto a condição é verdadeira no until é executado enquanto for falsa.

Exemplo:

Então em Shell Script temos esses três modos para repetição, os mais utilizados são for e while, os exemplos acima são apenas uma pequena amostra de como implementar porém começa a ficar interessante com o uso de array.

Array

Vetores ou arrays em qualquer linguagem de programação você irá utilizar ou se não irá implementar um modo de manipular e no Shell Script não é diferente, array pode ser declarado da seguinte maneira:

num[0]=”10″
num[1]=”20″
num[2]=”30″
num[3]=”40″
num[4]=”50″

ou

nomes=(“Cleiton” “Manoel” “Pedro” “Paulo”)

Vamos ao exemplo com o arquivo forEx1.sh:

Saída:

Agora um exemplo mais do dia-a-dia, vamos implementar um Shell Script para bloquear algumas portas com iptables, exemplo forEx2.sh:

Vamos entender o exemplo acima, temos o nosso array PORT=(“137” “138” “139” “445” “22” “80” “443”), onde eu criei um for que irá pegar o tamanho do array ${PORT[@]} e um a um vai sendo lido e armazenado no $porta onde executo minha regra de bloqueio com iptables.
Poderíamos melhoras esse script, separando as portas/serviços TCP dos UDP e colocando uma descrição, ficaria legal.
Vamos então ao exemplo forEx3.sh:

Saída:

Esse ficou mais completo, foi a mesma ideia porem com mais dois arrays do protocol_portas e desc_portas, e temos uma variável $i do for que baseado no tamanho do array irá ser o identificado dos três arrays para exibir ou usar algum valor.

Agora um script útil utilizando o while, vamos ano nosso whileEx1.sh:

Saída:

Analisando o nosso arquivo de log:

Vamos entender nosso script. Ele faz parte de um processo que tenho onde começa a ser executado dia sim dia não onde varias coisas são feitas, porém ocorreu de algumas vezes esse meu script travar, e como eu sei que quando bem sucedido ele leva em torno de 6 horas, eu criei um outro script que é chamado e passado o PID desse meu script principal, então meu segundo script que é algo bem próximo ao exemplo acima irá monitorar o /proc/NUM_PID_FORNECIDO se este diretório existir quer dizer que o processo esta rodando e a sacada é o if [ date +%H%M -ge 1200 ], se o script for maior que 1200 seria 12:00 do dia ae sei que algo seu problema e o log é enviado para o meu e-mail para eu tomar as devidas providencias, no meu caso ele já é morto com um kill.
Foi uma pequena amostra do poder do Shell Script agora unindo if, while e variáveis, e para não virar bagunça apos enviar nosso arquivo de log por e-mail ele é removido no final do script se bem sucedido ou logo apos ultrapassar as 12horas de execução.

Nosso ultimo script dessa vez utilizando o for para uma tarefa de backup, vamos ver nosso forEx4.sh:

Agora foi uma promoção heim, ta lendo um e vai aprender dois *rs, como pode-se ver eu fiz dois scripts no nosso exemplo acima, vamos entender o primeiro Parte1, as variáveis DST e SRC dizem por si só que um serio o destino e outra a origem, eu acesso a origem na linha 7 e logo em seguida executo o comando find no diretório corrente e a saída ficara na variável LS_DIR, o meu find ira pesquisar tudo que for diretório -type d e estiver ali apenas -maxdepth 0 se eu coloca-se 1 seria 1 grau de dependência então avançaria até 1 diretório adiante.
Baseado no que estiver no LS_DIR sera os caminhos dos diretórios que eu irei compactar com o tar na linha12 e la esta o destino com o nome do .tgz e na frente cada diretório encontrado, então olha como se comporta essa primeira parte abaixo:

Na Parte2 tem uma sacadinha que fiz questão de mostrar e por isso dois exemplos, ele irá fazer algo importante, backup de “todos” os usuários do computador, muitos scripts na internet realizam backup de tudo que esta no /home, porém tem alguns usuários que o diretório padrão não é o home como Nagios e Zabbix e ae não se torna tão eficiente, e para este caso elaboramos o Parte2 do forEx4.sh.
As variáveis USER_ID e USER_DIR uma ira obter o UID de todos os usuários e a outra o diretório padrão, tenho DST_HOME que serão o destino do meu backup utilizei o /tmp para exemplo, e ae entro em uma estrutura de repetição de 0 até o numero total de elementos UID encontrados, onde por cada UID verifico se é maior que 1000 e menor que 65500, já que acima de 1000 são usuários comuns e abaixo de 1000 usuários do sistema, atendendo essa logica irei pegar o nome do usuário no /etc/passwd poderia usar regex no USER_DIR(preguiça rs), com isso em mãos é o mesmo tar utilizado agora apenas com uma variável de controle $i para identificar o usuário, vamos ver como se comportou a execução desta segunda etapa:

A maior sacada neste exemplo foi:
Parte1
LS_DIR=$(find * -maxdepth 0 -type d)
Parte2
USER_ID=($(cat /etc/passwd | cut -d: -f3))

Os dois executam comandos e armazenam em uma variável, a Parte1 é exatamente desta maneira já a Parte2 quando usamos VARIAVEL=($(COMANDO)), estou falando que meu resultado ira entrar em um array.

Espero ter passado a ideia de repetição e o uso da mesma em shell script foram vários exemplos e com praticas sem mais delongas que podem ser usadas no dia-a-dia, qualquer duvida insira um comentário.

Até a próxima!

Share Button

CC BY-NC-SA 4.0 Shell Script – Estrutura de repetição e arrays by Cleiton Bueno is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.