Como acionar uma notificação da Central de Notificações de um script AppleScript ou shell?

305

Eu adoraria poder tirar proveito dos recursos do Notification Center da 10.8 no AppleScripts e nos scripts de shell que escrevo.

Existe um comando interno ou uma biblioteca de terceiros que eu possa usar em um script AppleScript ou shell?

Idealmente, o tipo e o ícone da notificação poderiam ser controlados, mas mesmo a capacidade de acionar um banner básico com um ícone de estoque (mas texto personalizado) seria apreciada.

Nathan Greenstein
fonte

Respostas:

428

Com o Mavericks e versões posteriores, você pode fazer isso usando a 'notificação de exibição' do AppleScript:

display notification "Lorem ipsum dolor sit amet" with title "Title"

                          

É isso - literalmente simples! Há 3 rd bibliotecas -party ou aplicativos necessária e é totalmente portátil para uso em outros sistemas. Notificação 10.9 na parte superior, 10.10 DP no meio, 10.10 na parte inferior.

O AppleScript pode ser executado a partir do shell usando / usr / bin / osascript:

osascript -e 'display notification "Lorem ipsum dolor sit amet" with title "Title"'

Você também pode personalizar ainda mais o alerta adicionando…

  • uma legenda

    Acrescente 'subtítulo' seguido da sequência ou variável que contém o subtítulo.

    display notification "message" with title "title" subtitle "subtitle"

    O exemplo acima produz a seguinte notificação:

  • som

    Acrescente 'nome do som' seguido do nome de um som que será reproduzido juntamente com a notificação.

    display notification "message" sound name "Sound Name"

    Nomes de sons válidos são os nomes dos sons localizados em…

    • ~/Library/Sounds
    • /System/Library/Sounds

As notificações de postagem podem ser agrupadas como um script de linha de comando. O código a seguir pode ser executado no Terminal e adicionará um script a / usr / local / bin (deve existir, adicione a $ PATH) chamado notify.

cd /usr/local/bin && echo -e "#!/bin/bash\n/usr/bin/osascript -e \"display notification \\\"\$*\\\"\"" > notify && chmod +x notify;cd -

Este é o script que o acima irá adicionar para notificar.

#!/bin/bash
/usr/bin/osascript -e "display notification \"$*\""

Agora, para exibir uma notificação:

notify Lorem ipsum dolor sit amet
sleep 5; notify Slow command finished
grg
fonte
9
@ceilingcat Este é o AppleScript. Para executá-lo no Terminal, use o osascript (veja a resposta).
grg
8
O único problema display notificationé que, quando você clica nele, a caixa de diálogo Abrir arquivo é exibida.
ɹoƃı
7
É possível fazer com que o pop-up de notificação exista para sempre (não oculte automaticamente após N segundos) até ser clicado explicitamente pelo usuário?
Sridhar Ratnakumar
25
Senhoras e senhores, depois de uma hora de investigação na rede mundial de computadores, descobri como deixar a janela de notificação permanecer até ser demitida pelo usuário! Na verdade, foi controlado por uma configuração na Preferência do sistema, em vez de algum parâmetro no script escrito. Essas duas imagens devem explicar tudo: i.imgur.com/cNOqFyX.jpg i.imgur.com/i8oyoan.jpg Divirta-se, pessoal, e obrigado @grgarside pela ótima resposta.
Vic Jang
4
Observe que o texto deve estar entre aspas duplas. Aspas simples não funcionam. Então, se você precisar de uma variável no texto, você não pode escrever "display ... '$mytext' ...", mas necessidade escaparam aspas: "display notification \"$mytext\" ...".
mivk
93

notificador de terminal

No README:

O notificador de terminal é uma ferramenta de linha de comando para enviar notificações de usuário do Mac OS X, disponíveis no Mac OS X 10.8.

Atualmente, ele é empacotado como um pacote de aplicativos, porque NSUserNotificationnão funciona em uma 'ferramenta Foundation'. radar: // 11956694

Esta ferramenta será usada pelo Kicker para mostrar o status dos comandos que são executados devido a alterações no sistema de arquivos. (v3.0.0)

Baixar

Binários pré-construídos, com código assinado e prontos para uso, estão disponíveis na seção de downloads .

Uso

$ ./terminal-notifier.app/Contents/MacOS/terminal-notifier group-ID sender-name message [bundle-ID]

Para usar o notificador de terminal, é necessário chamar o binário dentro do pacote de aplicativos.

O primeiro argumento especifica o 'grupo' ao qual uma notificação pertence. Para qualquer 'grupo', apenas uma notificação será exibida, substituindo as notificações postadas anteriormente. Os exemplos são: o ID do processo do remetente para definir o escopo das notificações por um processo exclusivo ou o diretório de trabalho atual para o escopo das notificações do projeto.

Os segundo e terceiro argumentos descrevem a notificação em si e são seu 'título' e 'mensagem', respectivamente. Por exemplo, para comunicar o remetente de uma notificação ao usuário, você pode especificar o nome do remetente como o título.

O quarto e último argumento é opcional. Ele especifica qual aplicativo deve ser ativado quando o usuário clica na notificação. Por padrão, isso ativará o Terminal.app, para iniciar outro aplicativo e, em vez disso, especificar o identificador de pacote do aplicativo. Por exemplo, para lançar o uso Safari.app: com.apple.Safari.

Steve Moser
fonte
Doce, uma ótima biblioteca! Gostaria de vê-lo atualizado com controle sobre o ícone e alerta vs banner, mas definitivamente útil. Obrigado pelo link! i.imgur.com/tsCeK.png
Nathan Greenstein
2
Ótimo aplicativo, criei um iniciador e coloquei / usr / local / bin para poder usá-lo em qualquer lugar do terminal, etc. Script do iniciador: #! / Bin / bash cd /Applications/terminal-notifier.app/Contents/ MacOS ./terminal-notifier $ *
johanandren
4
O Launcher é útil, se você o alterar um pouco, ele funciona com texto entre aspas com espaços: #! / Bin / bash cd /Applications/terminal-notifier.app/Contents/MacOS ./terminal-notifier "$ @"
Redbeard
27

Eu só quero adicionar uma nota à resposta do @ grgarside, porque sei que muitas pessoas desejam ter um pop-up de notificação que só pode ser descartado com o clique do botão.

Comparação

Encontrei a solução para você:

Na verdade, foi controlado por uma configuração na Preferência do sistema, em vez de algum parâmetro no script escrito. Essas duas imagens devem explicar tudo

Obrigado @grgarside pela ótima resposta.

Preferência do sistema

Vic Jang
fonte
5
Observe que o aplicativo específico varia. Script Editoré apenas para Script Editor.appe osascript. Em um fluxo de trabalho de serviço, é Automator Runner. Quando dentro Automator.app, é Automator.
Cde 22/03
1
Acho irritante que, se eu clicar no Banner, ele abrirá o aplicativo Editor de Script. Gostaria que ele simplesmente desaparecesse com o clique, mas este post indica que você pode passar o mouse sobre ele e deslizar o mouse para a direita para fazê-lo desaparecer silenciosamente: osxdaily.com/2012/09/05/…
Joshua Goldberg
@JoshuaGoldberg Obrigado por adicionar isso! Descobri isso intuitivamente, um dia, que é uma coisa que eu gosto sobre o Mac OS X, ele funciona da maneira que você espera que ele faça o trabalho :)
Vic Jang
22

Agora você pode fazer isso com o Growl2 ( disponível na App Store ). Instale o Growl e ative "OS X Notifications" (captura de tela)

insira a descrição da imagem aqui

Além disso, você precisará instalar o GrowlNotify para uma ferramenta de linha de comando para enviar notificações de Growl. Você pode baixar essa ferramenta gratuitamente na página de Download .

Agora você pode gerar notificações de Growl na linha de comando, que será encaminhada para o Centro de Notificações. Por exemplo:

growlnotify -n "My App" -m "Hello world"

insira a descrição da imagem aqui

Observe que atualmente não parece possível alterar o ícone do aplicativo.

Gerry
fonte
1
Boa abordagem, especialmente se o rosnado já estiver instalado.
Besi
1
Eu acho que você pode usar a opção --icon path/to/icon.pngpara ícones.
Será
Descontinuado / não é mais mantido? A última atualização foi para o macos 10.9 mavericks
Seamus
15

Recentemente, bifurquei o terminal-notifier para criar uma ferramenta de linha de comando para exibir alertas de notificação (com ações) e alertas de tipo de resposta.

Eu o uso com meus scripts de shell e aplicativos golang para obter respostas interativas dos usuários.

https://github.com/vjeantet/alerter

insira a descrição da imagem aqui

vjeantet
fonte
1
Também aparentemente obsoleto / abandonado.
Seamus
15

A solução do @grgarside é boa, mas é vulnerável à injeção de scripts, que pode ser um grande problema de segurança quando usado para, por exemplo, exibir o conteúdo do arquivo de log ou algo semelhante.

Isso deve ser mais seguro:

#!/bin/bash
X="$*" /usr/bin/osascript -e 'display notification system attribute "X"'
Archimedix
fonte
isso é interessante, mas você pode descrever um cenário em que um script executado no meu sistema que é apenas executável pelo usuário é vulnerável à injeção de scripts?
Iconoclast
1
Se você exibir conteúdo do usuário que não é seu, você estará vulnerável. Por exemplo, se você executa isso em um sistema com um servidor público da Web, ou quando algum aplicativo registra as seqüências obtidas da rede, as quais você lê e exibe, por exemplo, um navegador, programa de email ou cliente do Twitter. Poderia ter um "para terminar a string e a instrução, depois ter código e depois reiniciar uma string. #
Archimedix
ok, é verdade. é apenas difícil para mim imaginar colocar conteúdo de formulários da web nas minhas notificações, mas o seu argumento está correto.
Iconoclast
1
Bem, talvez você gostaria de dizer algo como, I have a "laser"sem ser informado de que está tendo um erro de sintaxe ao "citar" suas "palavras". Com a fuga, você pode:script 'I have a "laser"'
Archimedix
1
Voto positivo, porque sempre é bom ter em mente a segurança. Alguém poderia copiar soluções de massas e usá-las de maneiras que a pessoa que postou a solução não havia considerado.
Edward Falk
13

Como o Growl não é gratuito e o notificador de terminal não está disponível nos sistemas anteriores à 10.8, eu costumo usar o cocoaDialog . É gratuito e de código aberto, portanto você provavelmente também pode distribuir junto com seus scripts.

Se você não precisar de muita personalização, também poderá usar os AppleScript, display notificationque também podem ser chamados a partir do shell, como outros já mencionaram.

Mas lembre-se de que o AppleScript parece exigir aspas duplas. Portanto, se você precisar de variáveis, isso não funcionará :

osascript -e "display notification '$text' with title '$title'" #WRONG

Você terá que usar aspas duplas. Isso é feio, mas funciona :

osascript -e "display notification \"$text\" with title \"$title\""
mivk
fonte
Isso também funciona:osascript -e 'display notification "Lorem ipsum dolor sit amet" with title "Title"'
MikeSchinkel 12/17/17
Também obsoleto. Rendimentos do link "Não há um site de páginas do GitHub aqui".
Seamus
11

(Esta é uma implementação alternativa baseada na excelente resposta do @ grgarside.)

AppleScript pode ser interpretado diretamente colocando osascripta linha shebang.

#!/usr/bin/osascript

on run argv
    if length of argv = 1 then
        display notification (item 1 of argv) with title "Notification"
    else if length of argv > 1 then
        display notification (item 1 of argv) with title (item 2 of argv)
    else
        return "<message> is required\nUsage: notify <message> [<title>]"
    end if
end run

Salve isso como notifyem algum lugar do seu caminho, por exemplo /usr/local/bin/notify, e torne-o executável ( chmod +x notify). Aceita uma mensagem e um título opcional. Se um tiver espaço em branco, coloque-o entre aspas para que o shell o interprete como um único argumento.

$ notify "Lorem ipsum dolor sit amet" "Testing Notifications"
Steve
fonte
Isso evita os ataques de injeção de que todas as outras respostas são vulneráveis a
Neil Mayhew
7

Aqui está um que eu uso em um script ruby ​​no OS X (para que eu possa iniciar um script e obter uma atualização mesmo depois de sair da janela):

cmd = %Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
system ( cmd )
JayCrossler
fonte
2
uau ... então a cadeia é algo como Usuário -> Ruby -> Shell -> AppleScript -> Objective-C -> Assembly -> CPU?
Iconoclast
5

Uma alternativa:

Em .bash_profile:

function _sys_notify() {
    local notification_command="display notification \"$2\" with title \"$1\""
    osascript -e "$notification_command"
}
alias sys-notify="_sys_notify $1 $2"

Use o comando: sys-notify "title" "message"

ronald8192
fonte
5

Documentação oficial

https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/DisplayNotifications.html

Copiando o texto aqui, caso o documento seja movido ou removido.

Para mostrar uma notificação, forneça ao comando de notificação de exibição uma sequência a ser exibida. Opcionalmente, forneça valores para os parâmetros com título, legenda e nome do som para fornecer informações adicionais e um alerta sonoro quando a notificação aparecer

display notification "All graphics have been converted." with title "My Graphic Processing Script" subtitle "Processing is complete." sound name "Frog"

NOTA

Depois de usar um script para exibir uma notificação, o script ou o Editor de scripts (se o script for executado no Editor de scripts) será adicionado à lista de aplicativos de notificação em Preferências do sistema> Notificações. Lá, você pode configurar opções, como exibir notificações como alertas ou banners.

Clicar no botão Mostrar em uma notificação no estilo de alerta abre o aplicativo que exibiu a notificação. Para um aplicativo de script, a ação de abrir o aplicativo novamente aciona o manipulador de execução do script, potencialmente fazendo com que o script comece a processar pela segunda vez. Lembre-se disso e adicione código ao seu script para lidar com esse cenário, se apropriado.

nishanths
fonte
1

Obrigado, era exatamente o que eu precisava para alguns scripts de usuário. Fiz uma ligeira modificação para adicionar legenda e som. Se um valor não for fornecido, ele será ignorado.

function _sys_notify() {
local notification_command="display notification \"$2\" with title \"$1\" subtitle \"$3\" sound name \"$4\""
osascript -e "$notification_command"
}

alias sys-notify="_sys_notify $1 $2 $3 $4"

Para o som, use um nome de arquivo de som sem a extensão de / System / Library / Sounds. Por exemplo, para usar o arquivo Ping.aiff, use Ping por US $ 4

Kevin Mason
fonte