Faça o ícone do Terminal pular, e outros truques de notificação em scripts

A necessidade de chamar a atenção do operador mesmo se ele não estiver olhando para a tela é bem mais antiga que os nossos microcomputadores: um caracter de controle que faz o dispositivo ecoar um sino já estava presente até mesmo no tempo dos terminais de fita perfurada e teletipos (incluindo o Telex), e sua origem pode ser encontrada na década de 1870.

Soar uma sineta ainda é possível nos terminais atuais, mas as características multimídia de nossos computadores fazem do modesto sinal sonoro uma forma muitas vezes insuficiente de chamar a atenção do operador que pode estar atento a outra janela.

Entra em cena o caracter ␇ do Lion

O caracter BEL é a personificação da sineta clássica dos terminais, e pode ser representado de muitas formas: na entrada de dados clássica ele é o ^G (Control + G), na tabela ASCII ele é o código 07, na linguagem C (e em sistemas com sintaxe derivada) ele é o  ("alert"), e assim por diante.

Em terminais "físicos" (hoje raros), tentar imprimir o caracter BEL fazia soar a sineta, e este comportamento é reproduzido em vários terminais virtuais modernos (ou ao menos oferecido como uma opção de configuração).

A partir do OS X Lion, entretanto, o BEL aprendeu um truque extra: se o Terminal ou aba em que ele for "impresso" não estiver em primeiro plano, ele tocará o som de alerta do teclado como esperaríamos, mas também fará seu ícone pular na Dock, e incluirá/incrementará um contador de eventos junto a ele, como o da imagem acima (se a janela do Terminal estiver em primeiro plano, ele só tocará o som, sem pulos nem contadores).

Para emitir o caracter BEL no teclado você pode recorrer a vários comandos, incluindo estes, em ordem de minha preferência:

  • tput bel
  • printf ""
  • echo -e ""

Para testar, vamos usar uma sequência simples de 3 comandos, sendo que os 2 primeiros são simplesmente uma forma de dar 5 segundos de tempo para você clicar em outra janela qualquer e garantir que o Terminal não esteja em primeiro plano na hora em que o BEL for impresso:

echo "Clique em outra janela AGORA e aguarde o beep"; sleep 5; tput bel

Fique de olho na Dock: em 5 segundos, se você tiver mesmo clicado em outra janela qualquer, o ícone do Terminal vai pular e ganhar o contador de eventos.

E é assim simples: se você quiser que o Terminal o notifique do completamento de algum comando, basta acrescentar o trecho ; tput bel ao seu final.

Por exemplo, para um desenvolvedor que usa ferramentas via linha de comando ser avisado ao final da longa compilação do sistema que ele está testando, pode simplesmente emitir o comando abaixo:

make; tput bel

... e ficar olhando o Twitter do @brmacblog enquanto compila, ciente de que será adequadamente notificado pelo Terminal quando a compilação terminar.

Para comandos bem-comportados (que sigam a convenção usual de registro de situações de erro), você também pode recorrer à execução condicional do alerta. Para executá-lo apenas se o comando anterior tiver sido bem-sucedido, acrescente o trecho && tput bel ao seu final; da mesma forma, para executá-lo apenas se o comando anterior tiver terminado em erro, acrescente o trecho || tput bel ao seu final.

Sons de alerta com estilo

O simples uso do caracter BEL gera um discreto tom sonoro de alerta, mas você pode querer optar por sons diferentes. Uma maneira simples de fazê-lo é recorrer à coleção de sons de notificação da biblioteca do sistema (dê uma olhada na pasta /System/Library/Sounds), por meio do comando afplay.

Para notificar audivelmente em caso de erro (cláusula ||), você pode optar usar o mesmo áudio que o OS X usa, como no exemplo abaixo:

ping -c 1 308.8.8.8 || afplay -v 9 /System/Library/Sounds/Funk.aiff

Este comando ping vai falhar, afinal o endereço que incluí nele é inválido. E quando ele falhar, a cláusula || permitirá que o comando afplay a seguir seja executado, tocando exatamente o Funk.aiff, usado na configuração default do OS X para indicar vários casos de erro.

Já para notificar em caso de sucesso (cláusula &&), uma alternativa é usar o Glass.aiff, também usado pelo OS X e por uma série de aplicativos. Exemplo:

ping -c 1 8.8.8.8 && afplay -v 9 /System/Library/Sounds/Glass.aiff

Se você estiver conectado à Internet, é provável que o ping acima funcione (8.8.8.8 é o servidor de DNS público do Google), e você ouvirá um som de toque em uma taça de vidro para indicar.

Vozes do além

Se você experimentou com todos os sons da pasta /System/Library/Sounds e não se satisfez, há algo diferente a testar, especialmente para situações incomuns (senão ninguém aguenta): fazer o OS X falar, usando o comando say.

Adaptando diretamente no exemplo do ping que falha, veja como fazer um aviso falado, usando a voz default do OS X, que fala em inglês:

ping -c 1 308.8.8.8 || say "ping failed"

O Growl também ajuda

Se você usa o sistema de notificação Growl (ou o fork gratuito do Growl), e instalou o utilitário growlnotify, pode fazer uso das suas bolhas de notificação também no Terminal ou em seus scripts.

Em uma forma bem simples, você poderia simplesmente chamar o growlnotify passando o texto da mensagem de erro a exibir. Voltando ao exemplo do ping que forçosamente dá errado:

ping -c 1 308.8.8.8 || growlnotify -m "Erro tentando ping em 308.8.8.8" -t "Script de teste"

Mas o Growl é bem mais rico que isso. Dá para incluir um ícone do seu sistema, por exemplo, ou mesmo garantir que o balão de mensagem ficará fixo na tela até que você ativamente o feche, como no exemplo:

ping -c 1 308.8.8.8 || growlnotify --sticky --image ~/Imagens/insira-o-nome-do-seu-icone.png -m "Erro tentando ping em 308.8.8.8" -t "Script de teste"

Claro que o growlnotify (assim como o say, o afplay, o tput e os demais comandos que abordamos hoje) possuem mais opções além das básicas que exploramos. Investigue-as, crie aliases, funções e outras estruturas com elas, e torne seus scripts mais dinâmicos e interativos!

Comentar

Comentários arquivados

Artigos recentes: