Bash - Truques e Dicas para o seu dia a dia
Bash = Born Again Shell
Faço esta publicação aos meus amigos e colegas de profissão que gostam de Linux e querem algumas dicas para melhorar os seus scripts em bash. Aqui aprenderemos alguns macetes úteis para o dia a dia.
Pré-requisitos:
Abra um terminal, pois você vai gostar de ver a mágica ocorrendo.
Aprender bash é como andar de bicicleta: Por mais que eu lhe ensine a teoria, o aprendizado só ocorre na prática.
Básico
Saiba que tudo o que você escrever no seu terminal, será primeiramente interpretado pelo bash, e então acionado o comando desejado.
Veja bem a palavra "interpretado" que escrevi acima.
É isso mesmo: Entre o comando executado no terminal e o acionamento do comando, existe uma etapa que poucos conhecem. E é ela que iremos explorá-la.
Desenharei o que acabei de dizer:
Muitos pensam que é assim:
Na verdade, o que temos:
Na prática ter um "bash" no meio do caminho possibilita fazer isso:
mkdir pasta_{1,2,3}
O que aconteceu acima foi:
Entendido o meu resumo básico acima? Então vamos para a parte prática!!
Prática
Como todo técnico gosta, vou ser extremamente objetivo:
Comando + breve explicação + print do resultado
Utilize a sua criatividade para fazer muito mais. A ideia aqui é abrir a sua mente.
Lembre-se: Utilizarei comandos como exemplo. Vou utilizar os mais conhecidos "echo, ls, mkdir, rm", mas poderia ser utilizado qualquer outro.
Vamos ao aprendizado de A a Z:
A) Listando de 0 a 50
echo {0..50}
B) Listando de 0 a 50, pulando de 10 em 10
echo {0..50..10}
C) Listando de Z a A
echo {Z..A}
D) Criar uma pasta para cada mes do ano
mkdir mes_{00..12}
E) Criar uma pasta por mês, desde o ano 2000
mkdir {2000..2020}_{01..12}
F) Listar todas as pastas do mês 10
ls | grep 10$
Note o "$" no final, significa tudo que TERMINAR com 10.
G) Listar todas as pastas iniciadas com 2000
ls | grep ^2000
Note o ^2000, significa tudo que iniciar por 2000.
H) Criar pastas cliente_A e cliente_B, contendo, dentro delas, todos os meses do ano de 2020
mkdir -p cliente_{A,B}/2020-{01..12}
I) Redirecionando saída para um arquivo
ls cliente_A > arquivo_A
Note o sinal ">".
Este sinal irá LIMPAR o arquivo + jogar a saída para ele
J) tee: Redirecionando saída para um arquivo + apresentando saída na tela
tee -> Joga a saída no stdout padrão e, também, para o arquivo informado por parâmetro
K) Adicionando informação no final do arquivo, sem substituir o conteúdo existente
>> -> Com dois ">", o conteúdo será adicionado no final do arquivo
L) Redirecionando a saída de erro para um arquivo
xxxxxx 2> a
O 2> é utilziado para redirecionar a saída de erro.
M) Redirecionando a saída de sucesso para o arquivo, mas a saída de erro para lugar nenhum
xxxxxx > a 2> /dev/null
N) Atribuindo variável, é tudo junto!
a=10 (certo - não utilize espaços)
a = 10(errado)
a= 10 (errado)
O) Somando
Note que "echo $c" é o correto, com "$".
P) Vários comandos em uma linha
Basta separar por ";" entreum comando e outro.
Q) Se o primeiro comando não retornar erro, então execute o segundo comando
a=100 && echo "Valor de a: $a"
&& -> Isso mesmo: cmd1 && cmd2
o cmd2 só será executado se o cmd1 tiver sucesso
Agora vamos fazer uma falha no primeiro comando:
R) Se o primeiro comando falhar, rode o segundo
a= 100 || echo "Valor de a: $a"
|| -> Note que agora utilizei dois pipes
Algo mais útil (Verificando se o arquivo existe):
S) Laço em bash - Rodando um PING para uma lista de IPs contendo em um arquivo chamado "ips"
for ip in cat ips
; do echo "ICMP PARA O IP: $ip"; ping -c 4 $ip | grep packets; echo ""; done
Peguei pesado agora, mas vamos lá.. vai rabiscando com calma:
T) Salvando comando em variável
U) Laço em bash - Outro exemplo, agora fazendo backup de todos os arquivos
arquivos_para_backup=ls
for arquivo in $arquivos_para_backup; do cp -rf $arquivo $arquivo.bkp; done
V) Loop eterno, monitorando um PING
while true; do ping -c 4 8.8.8.8; sleep 2; done
W) Loop eterno, salvando o resultado em arquivo e deixando a execução em background
while true; do ping -c 4 8.8.8.8 >> /tmp/meu_monitoramento.txt; sleep 2; done &
Explicando o comando:
while true; do -> Enquanto verdadeiro, faça um loop (sempre será verdadeiro.. loop eterno)
ping -c 4 8.8.8.8 >> /tmp/meu_monitoramento.txt; -> Roda 4 pings para 8.8.8.8 salvando no final do arquivo especificado
sleep 2; -> pause de 2 segundos antes de continuar o laço
done -> fim do laço
& -> Rodar o script em background. Portanto, você pode fechar o terminal e ir tomar um café.
X) Expressões regulares - Mostrar somente os IPs
cat ips | grep -E '^[0-9]*.'
Explicando:
^ -> Tudo que iniciar
[0-9] -> Que for dígito de 0 a 9
* -> Podendo ou não se repetir (os dígitos de 0 a 9)
\. -> Seguir de um ponto (a contra barra é um escape)
Y) Mesma lógica da anterior, agora com letras
Z) Dificultando um pouco e sendo mais específico - Filtrando os IPs um pouco melhor
cat ips | grep -E '^([0-9]{1,3}.){3}[0-9]{1,3}'
Note que adicionei alguns ips "fakes" no início do arquivo.
Explicando:
^ -> Tudo que iniciar
([0-9]{1,3}.) -> Dígitos de 0 a 9, podendo se repedir de 1 a 3 vezes, e terminado por .
{3} -> A regra agrupada anteriormente que está entre ( ), deve se repetir 3x
[0-9]{1,3}$ -> Que finalize com dígitos de 0 a 9, podendo se repedir de 1 a 3 vezes
Finalizando
Espero que este post possa ajudar você a entender um pouco mais sobre bash!
Com uma pitada de criatividade é possível evoluir muito com cada um dos comandos acima apresentados.
E aí, gostou?
Autor: Ronaldo Sacco