Ser avisado quando um comando longo termina no terminal

Pare de ficar de babá de um build de quarenta minutos. Uma linha depois de qualquer comando manda o resultado para o seu celular, inclusive se você já saiu.

Atualizado

Sumário

Você dispara um treinamento, uma suíte de testes completa, um docker build ou um agente de código numa tarefa longa. Aí sobram duas opções ruins: sentar e olhar uma barra de progresso, ou sair e voltar vinte minutos depois para descobrir que falhou aos noventa segundos.

Existe uma terceira opção e ela cabe em uma linha.

A linha

Crie um canal no Echobell, copie a URL de webhook dele e acrescente isto depois do que você estiver rodando:

pnpm build; curl -sS -X POST https://hook.echobell.one/t/SEU_TOKEN \
  -H 'content-type: application/json' \
  -d '{"title":"build terminou","body":"echobell-web"}'

Repare no ; e não no &&. Com && a notificação só dispara quando o comando dá certo, o que é exatamente ao contrário: a falha é o caso sobre o qual você mais quer saber.

Mande o código de saída também

Uma notificação que diz "terminou" conta metade da história. Capture o status:

pnpm build; s=$?; curl -sS -X POST https://hook.echobell.one/t/SEU_TOKEN \
  -H 'content-type: application/json' \
  -d "{\"title\":\"build $([ $s -eq 0 ] && echo ok || echo FALHOU)\",\"status\":\"$s\"}"

s=$? precisa vir imediatamente depois do comando — qualquer coisa no meio, incluindo o próprio teste [, sobrescreve $?.

Transforme numa função de shell

Digitar isso toda vez derruba o propósito. Coloque isto no ~/.zshrc ou ~/.bashrc:

notify() {
  "$@"
  local status=$?
  curl -sS -X POST "$ECHOBELL_HOOK" \
    -H 'content-type: application/json' \
    -d "{\"command\":\"$*\",\"status\":\"$status\",\"host\":\"$(hostname -s)\"}" \
    >/dev/null
  return $status
}

Defina ECHOBELL_HOOK no perfil do seu shell — ou melhor, mantenha fora do repositório de dotfiles e exporte de um arquivo que você não versiona. Depois:

notify pnpm test
notify cargo build --release
notify python train.py

O return $status no fim importa: mantém o notify transparente, então notify make && ./deploy.sh continua se comportando como você espera.

Com esse payload, os templates do canal podem ser:

Título

{{command}} · {{status}}

Corpo

em {{host}}

Só me ligue quando falhar

A maioria das execuções dá certo e você não precisa ouvir sobre elas. Dois canais resolvem isso direito: um normal para tudo e um de chamada com uma condição:

status != "0"

Aponte o notify para o segundo canal naquilo que faria você levantar da cama, e as execuções bem-sucedidas ficam em silêncio.

Sobrevivendo a um notebook fechado e a uma sessão SSH caída

Se o comando roda por SSH, fechar o notebook mata o shell e a notificação nunca sai. Duas saídas:

tmux — inicie o comando dentro de uma sessão e desanexe:

tmux new -d -s build 'notify pnpm build'

nohup — para uma vez só:

nohup bash -c 'notify pnpm build' >/dev/null 2>&1 &

Nos dois casos o processo sobrevive à sua conexão, e a notificação chega estando você conectado ou não.

Agentes de código com IA

O mesmo padrão cobre um agente de CLI trabalhando numa tarefa longa:

notify codex exec "refatore o módulo de pagamentos e rode os testes"

Para agentes que param no meio e esperam por uma pessoa — uma aprovação, um pedido de permissão — uma notificação de conclusão é a ferramenta errada, porque a execução não terminou. Esse caso pede o hook ou callback do próprio agente, e merece uma ligação em vez de um push. Transformar aprovações de agente em ligações cobre isso, incluindo o hook Notification do Claude Code e seu matcher agent_needs_input.

Use os dois: o hook para "estou travado", a função de shell para "terminei".

O que não colocar na notificação

A saída do comando, não. É tentador jogar as últimas linhas de um build que falhou no corpo. Resista: logs de build contêm tokens, strings de conexão e dados de cliente com mais frequência do que se imagina, e o corpo de uma notificação acaba numa tela bloqueada. Mande o código de saída e vá olhar o terminal.

A URL do canal, também não, num repositório público de dotfiles. Qualquer um com a URL pode postar no seu canal. Guarde num arquivo fora do versionamento e ligue Somente POST, para uma prévia de link perdida não disparar nada.

Perguntas frequentes

Por que não usar terminal-notifier ou notify-send?

Esses mostram uma notificação na máquina que roda o comando. Funcionam enquanto você está sentado nela. O ponto desta montagem é o caso em que você não está: uma máquina remota, um notebook fechado, outro cômodo.

Funciona no Windows?

O padrão sim, a sintaxe muda. No PowerShell o equivalente é Invoke-RestMethod -Method Post -Uri $env:ECHOBELL_HOOK -ContentType application/json -Body $json, com $LASTEXITCODE no lugar de $?.

Consigo receber no relógio?

Sim. As assinaturas entregam num Apple Watch pareado, que é sinceramente o formato certo para "o build acabou".

E se o comando levar 12 horas?

Nada nessa montagem expira — o curl roda quando o comando retorna. Execute sob tmux para que uma queda de conexão não leve o processo junto.

Meus colegas podem receber as mesmas notificações?

Podem. Compartilhe o canal e cada assinante escolhe o próprio tipo de notificação. Útil numa máquina de treinamento compartilhada onde mais de uma pessoa se importa que a GPU ficou livre de novo.

Fechando

Uma função de shell, um canal, e uma condição se você só quer as falhas. Leva uns dois minutos para montar e devolve os vinte que você passa olhando barra de progresso.

Baixe o Echobell para iPhone ou pegue no Google Play, depois teste em algo demorado o bastante para você sair de perto.


Conteúdo relacionado