Continuando os trabalhos do artigo Ferramenta pra verificar quantidades de dias válidos de um certificado do letsencrypt, fiz uma pequena entrada na crontab pra chamar um script que fiz em fish.
# tail -1 /etc/crontab
0 1 */5 * * root /root/bin/check-domain-expiration-dates.fish >> /tmp/certificate_renew.log 2>&1
E o respectivo script:
#! /usr/bin/env fish
set EXPIRATION_DAYS 10
for info in (letsencrypt-cert-days)
set domain (echo $info | cut -d"=" -f1)
set days (echo $info | cut -d"=" -f2)
if [ $days -lt $EXPIRATION_DAYS ]
echo "Renewing domain: $domain"
certbot renew -d $domain
end
end
Então eu rodo no crontab a cada 5 dias pra detectar se algum certificado está expirando. E então chamo o `certbot` pra renovar se for o caso.
Funciona? Não sei. Meus certificados estão válidos ainda por quase 50 dias. Daqui um mês eu atualizo se funcionou.
# letsencrypt-cert-days --domain=helio.loureiro.eng.br
helio.loureiro.eng.br=48
.oO(nota mental: trocar crontab por systemd-timer)
Nada muito glamoroso. Só um script usando utf-8 pra fazer uma caixinha bonitinha em volta do texto.
#!/usr/bin/env bash
sizeof() {
local msg="$1"
local size=$(echo $msg | wc -L)
# one space at beginning and other at the end
size=$((size+2))
echo $size
}
printchar() {
local char="$1"
local nr="$2"
while [ $nr -gt 0 ]
do
echo -ne "$char"
nr=$((nr-1))
done
}
printbox() {
local msg="$1"
local s=$(sizeof "$msg")
echo -n "┌"
printchar "─" $s
echo "┐"
echo -e "│ ${msg} │"
echo -n "└"
printchar "─" $s
echo -e "┘\n"
}
message="$@"
printbox "$message"
O código também está publicado no GitHub.
Esse é um código que estamos usando bastante aqui na firma nova. Ajuda a fazer seu script decidir se segue em frente ou para. E basta apenas apertar uma teclar, sem enter.
#! /usr/bin/env bash
read -p "Deseja continuar (s/n)? " -n 1 -r resposta
if [[ "$resposta" =~ [sS] ]];then
echo "Resposta foi sim"
else
echo "Resposta foi não"
fi
Como um tsunami, Elon Musk assumiu o Twitter e literalmente varreu como uma onde destruidora a empresa. De cara mandou metade pra rua, depois pediu code review pra cada um que ficou e deu prazo para irem trabalhar fisicamente na empresa ou automaticamente estariam demitidos. Claro que as coisas não foram muito bem. E no momento atual continuam indo por água abaixo.
Enquanto isso redes alternativas ganharam tração, entre elas a Mastodon. Ao contrário do Twitter, Mastodon não é uma empresa ou uma rede: é um conjunto de servidores conversando o mesmo protocolo e que se comunicam entre si. Eu já tinha uma conta na instância mastodon.social, onde tudo surgiu. Mas desde que foi criada, em 2015, eu tinha postado 2 mensagens. E só. Nunca teve muita gente ali pra conversar pra tornar a rede minimamente interessante.
Mas com a ascensão do Elon ao Twitter isso tudo mudou. E pra melhor. Muita gente interessante migrou pra rede Mastodon, ao ponto de atingir o efeito rede e manter um crescimento sustentando em termos de usuários e posts. Se os servidores vão aguentar esse tráfego, daí já são outros 500.
No Twitter eu automatizava muita coisa. Então pra mim era essencial ter as mesmas coisas no Mastodon. Eu primeiramente descobri o programa "toot", em Python. Com ele é possível criar posts usando shell script (e na verdade foi o que fiz de início).
Não sei se tem pacotes pra instalar o toot, mas eu usei o pip do próprio python pra instalar.
helio@MacOS> pip3 install toot
Com isso o programa "too" vai parar em ~/.local/bin, que eu já tenho na minha variável PATH, então funciona no shell. Mas é preciso corrigir o PATH se for usar num script via crontab (como eu fiz depois).
O começo é criar um login na instância que for usar. Eu por exemplo comecei com
helio@MacOS> toot loginThis email address is being protected from spambots. You need JavaScript enabled to view it. helio@MacOS> toot login -iThis email address is being protected from spambots. You need JavaScript enabled to view it.
As configurações ficam armazenadas num arquivo for json em ~/.config/toot/config.json, o que depois facilitou minha vida pra criar scripts em python (mas que vou descrever em outro artigo).
Daí você pode começar a mandar mensagens usando a conta padrão ou usando o "-i" pra qual instância quer mandar.
helio@MacOS> toot post "testing"
E o toot aceita mesmo passar conteúdo via pipe:
helio@MacOS> uname -a | toot post
Pra subir imagens e usando minha instância que posto em português:
helio@MacOS> toot activate helioloureiroBR@This email address is being protected from spambots. You need JavaScript enabled to view it.
✓ User helioloureiroBR@This email address is being protected from spambots. You need JavaScript enabled to view it. active
helio@MacOS> toot post "só li verdades" --media=$HOME/Pictures/chicobuarque-mastodon.jpg
Uploading media: /Users/ehellou/Pictures/chicobuarque-mastodon.jpg
Toot posted: https://mastodon.social/@helioloureiroBR/109410489057504335
Então é possível ver as possibilidades infinitas de scripts em shell com o uso de toot.
Pra terminar o artigo, deixo aqui a imagem muito significativa que enviei no teste. Afinal não existe prazer maior na vida que ajudar um bilionário a ficar milionário.
Em tempo: eu não apaguei minhas contas no Twitter. Estão lá mas inativas.
Durante a apresentação do grande prof. Júlio Neves na BSD Day 2022 sobre shell, ele fez uma comparação interessante sobre shell ser dito lento. E mostrou o seguinte slide:
Eu achei muito interessante o exemplo, mas resolvi testar ele pra valer.
Então testei não com 200 interações, mas com 20 milhões. Daí sim a coisa fica mais interessante.
Fiz o mesmo script em shell:
#! /usr/bin/env bash
for ((i=1; i<20000000; i++)) {
: > arq-shell
}
Em python:
#! /usr/bin/env python3
for i in range(20000000):
with open("arq-python3", "w") as fd:
None
em perl:
#! /usr/bin/env perl
for ($i=0;$i<20000000;$i++) {
open(FD, ">arq-perl");
}
e finalmente em Go:
package main
import (
"log"
"os"
)
func main() {
for i := 0; i < 20000000; i++ {
fd, err := os.Create("arq-go")
fd.Close()
if err != nil {
log.Fatal(err)
}
}
}
Os resultados foram os seguintes:
helio@goosfraba /t/comparacao-shell> time ./20M-touch.sh
________________________________________________________
Executed in 303.69 secs fish external
usr time 164.93 secs 0.00 micros 164.93 secs
sys time 133.79 secs 533.00 micros 133.79 secs
helio@goosfraba /t/comparacao-shell> time./20M-touch.py
________________________________________________________
Executed in 374.49 secs fish external
usr time 225.16 secs 623.00 micros 225.16 secs
sys time 143.90 secs 125.00 micros 143.90 secs
helio@goosfraba /t/comparacao-shell> time ./20M-touch.pl
________________________________________________________
Executed in 173.94 secs fish external
usr time 47.95 secs 1.05 millis 47.95 secs
sys time 122.10 secs 0.00 millis 122.10 secs
helio@goosfraba /t/comparacao-shell> time ./20M-touch
________________________________________________________
Executed in 147.80 secs fish external
usr time 45.82 secs 579.00 micros 45.82 secs
sys time 107.38 secs 113.00 micros 107.38 secs
Eu achei os resultados um pouco miseráveis pra python. Então re-escrevi a função como era feito desde o python 1.2 (usando 3.10.4):
#! /usr/bin/env python3
for i in range(20000000):
fd = open("arq-python3", "w")
fd.close()
e o resultado não melhorou muita coisa.
helio@goosfraba /t/comparacao-shell> time ./20M-touch.py
________________________________________________________
Executed in 370.23 secs fish external
usr time 218.59 secs 641.00 micros 218.59 secs
sys time 146.02 secs 132.00 micros 146.02 secs
Acho que agora os números falam por si só sobre shell ser lento ou não. Claro que pra coisas mais simples é bem mais fácil fazer em shell, mas isso não significa um desempenho melhor.
Tirando essa parte de desafio, a palestra foi espetacular. Quem não viu, recomendo que assistam.