Wie kann ich eine Notification Center-Benachrichtigung von einem AppleScript oder Shell-Skript auslösen?

Ich würde gerne die Funktionen des Benachrichtigungszentrums von 10.8 in AppleScripts und Shell-Skripts, die ich schreibe, nutzen können.

Gibt es einen integrierten Befehl oder eine Bibliothek eines Drittanbieters, die ich entweder aus einem AppleScript oder einem Shell-Skript verwenden kann?

Idealerweise könnten Typ und Symbol der Benachrichtigung gesteuert werden, aber auch nur die Möglichkeit, ein einfaches Banner mit einem Bestandssymbol (aber benutzerdefiniertem Text) auszulösen, wäre wünschenswert.

Antworten (13)

Mit Mavericks und höher können Sie dies mit AppleScripts „Anzeigebenachrichtigung“ tun:

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

                          

Das ist es – buchstäblich so einfach! Keine Bibliotheken oder Apps von Drittanbietern erforderlich und vollständig portabel für die Verwendung auf anderen Systemen . 10.9 Benachrichtigung oben, 10.10 DP in der Mitte, 10.10 unten.

AppleScript kann von der Shell mit /usr/bin/osascript ausgeführt werden:

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

Sie können die Warnung auch weiter anpassen, indem Sie hinzufügen…

  • ein Untertitel

    Hängen Sie „subtitle“ an, gefolgt von der Zeichenfolge oder Variable, die den Untertitel enthält.

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

    Das obige Beispiel erzeugt die folgende Benachrichtigung:

  • Klang

    Hängen Sie „Soundname“ an, gefolgt vom Namen eines Sounds, der zusammen mit der Benachrichtigung abgespielt wird.

    display notification "message" sound name "Sound Name"
    

    Gültige Soundnamen sind die Namen von Sounds in …

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

Posting-Benachrichtigungen können als Befehlszeilenskript verpackt werden. Der folgende Code kann in Terminal ausgeführt werden und fügt ein Skript mit dem Namen /usr/local/bin hinzu (muss vorhanden sein, zu $PATH hinzufügen) notify.

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

Dies ist das Skript, das oben zur Benachrichtigung hinzugefügt wird.

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

Jetzt eine Benachrichtigung anzeigen:

notify Lorem ipsum dolor sit amet
sleep 5; notify Slow command finished
Was ist der Pfad von display? Ich habe Mavericks, aber ich kann es nicht sehen. Danke!
@ceilingcat Könnten Sie klarstellen, was Sie meinen? Was funktioniert nicht?
I got -bash: display: command not foundMy path is irgendwie verrückt, also wäre es schön zu wissen, wo sich genau displaybefindet.
@ceilingcat Das ist AppleScript. Um es im Terminal auszuführen, verwenden Sie osascript (siehe Antwort).
Das einzige Problem display notificationdabei ist, dass beim Anklicken der Datei-Öffnen-Dialog erscheint.
Ist es möglich, dass das Benachrichtigungs-Popup für immer existiert (nicht nach N Sekunden automatisch ausgeblendet wird), bis der Benutzer explizit darauf klickt?
Wie füge ich ein Zeitlimit hinzu, damit die Benachrichtigung auf dem Bildschirm erscheint?
Paar Fragen - 1. Irgendwie kann ich bestimmte Aktionen hinzufügen, wenn ich auf die Benachrichtigung klicke? Angenommen, ich möchte ein bestimmtes Shell-Skript ausführen. Ich bin auf Yosemite und es startet den Dateibrowser. 2. Wie passe ich die Benachrichtigung mit weiteren Optionen an, z. B. das Anzeigen einer Schaltfläche an der Seite, wenn Sie mit der Maus darüber fahren, z. B. was passiert, wenn der nächste iTunes-Song automatisch abgespielt wird und eine Benachrichtigung mit diesem Titel angezeigt wird, oder wenn Sie auf die Benachrichtigung klicken, wenn Sie Wenn Sie eine neue Nachricht haben, werden zwei Optionen angezeigt - Senden und Abbrechen?
Nichts, was ich gefunden habe, weist darauf hin, dass es eine Möglichkeit gibt, die Aktion zu steuern (was passiert, wenn Sie auf die Benachrichtigung klicken). macosxautomation.com/mavericks/notifications/01.html ist praktisch, FYI.
Meine Damen und Herren, nach einer Stunde Recherche im World Wide Web habe ich herausgefunden, wie ich das Benachrichtigungsfenster so lange stehen lassen kann, bis es vom Benutzer geschlossen wird! Es wurde tatsächlich durch eine Einstellung in den Systemeinstellungen gesteuert und nicht durch einen Parameter im geschriebenen Skript. Diese beiden Bilder sollten alles erklären i.imgur.com/cNOqFyX.jpg i.imgur.com/i8oyoan.jpg Viel Spaß Jungs und danke @grgarside für die tolle Antwort.
Beachten Sie, dass der Text in doppelten Anführungszeichen stehen muss. Einfache Anführungszeichen funktionieren nicht. Wenn Sie also eine Variable im Text benötigen, können Sie nicht schreiben "display ... '$mytext' ...", sondern doppelte Anführungszeichen mit Escapezeichen: "display notification \"$mytext\" ...".
display notificationfunktioniert bei mir nicht auf El Capitan, obwohl es display alertgut funktioniert. Die Dokumentation behauptet, dass beide funktionieren. Irgendwelche Erkenntnisse dazu?
Wie Vic Jang erwähnt, aber nicht klar erklärt hat, können Sie die Einstellungen für die Anzeige der Benachrichtigungen über Systemeinstellungen > Benachrichtigungen > Skripteditor > Änderung von "Banner" zu "Benachrichtigungen" ändern. Auf diese Weise können Sie zumindest auf „Schließen“ klicken, anstatt den Dialog „Datei öffnen“ zu sehen, wenn Sie die Benachrichtigung schließen.
@Dan Das Klicken auf eine Benachrichtigung ist niemals eine Entlassungsaktion, weshalb der Skripteditor beim Klicken gestartet wird. Sie können ein Banner mit einem Wischen mit zwei Fingern schließen, während Sie es schweben lassen. Eventuell schaue ich mal nach Alternativen, wenn ich Zeit habe.
benutzerdefiniertes Bild für Benachrichtigung?
Anscheinend sound namekönnen Sie keine benutzerdefinierten Sounds ~/Library/Soundsmehr abspielen. Weiß jemand Abhilfe? Mit macOS 10.13.2.
Auf Mac 11.2.3:zsh: command not found: display
@Alik Bitte lesen Sie die Antwort, insbesondere: 'AppleScript kann mit /usr/bin/osascript von der Shell ausgeführt werden'
Ich musste den „Notification Center“-Prozess beenden, der automatisch neu gestartet wird, bevor die Benachrichtigung auftauchte.

Terminal-Notifier

Aus der README:

terminal-notifier ist ein Befehlszeilentool zum Senden von Mac OS X-Benutzerbenachrichtigungen, die in Mac OS X 10.8 verfügbar sind.

Es ist derzeit als Anwendungspaket verpackt, da NSUserNotificationes nicht mit einem „Foundation Tool“ funktioniert. radar://11956694

Dieses Tool wird von Kicker verwendet , um den Status von Befehlen anzuzeigen, die aufgrund von Dateisystemänderungen ausgeführt werden. (v3.0.0)

Download

Vorgefertigte Binärdateien, die Code-signiert und gebrauchsfertig sind, sind im Download-Bereich verfügbar .

Verwendung

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

Um Terminal-Notifier zu verwenden, müssen Sie die Binärdatei im App-Bundle aufrufen.

Das erste Argument gibt die „Gruppe“ an, zu der eine Benachrichtigung gehört. Für jede „Gruppe“ wird immer nur eine Benachrichtigung angezeigt, die zuvor gepostete Benachrichtigungen ersetzt. Beispiele sind: die Prozess-ID des Absenders, um die Benachrichtigungen einem eindeutigen Prozess zuzuordnen, oder das aktuelle Arbeitsverzeichnis, um Benachrichtigungen einem Projekt zuzuordnen.

Das zweite und dritte Argument beschreiben die Benachrichtigung selbst und sind ihr „Titel“ bzw. ihre „Nachricht“. Um dem Benutzer beispielsweise den Absender einer Benachrichtigung mitzuteilen, könnten Sie den Namen des Absenders als Titel angeben.

Das vierte und letzte Argument ist optional. Es gibt an, welche Anwendung aktiviert werden soll, wenn der Benutzer auf die Benachrichtigung klickt. Standardmäßig wird dadurch Terminal.app aktiviert, um eine andere Anwendung zu starten, geben Sie stattdessen die Bundle-ID der Anwendung an. Um beispielsweise Safari.app zu starten, verwenden Sie: com.apple.Safari.

Süß, eine tolle Bibliothek! Würde gerne sehen, dass es mit der Kontrolle über das Symbol und den Alarm vs. Banner aktualisiert wird, aber auf jeden Fall nützlich. Danke für den Link! i.imgur.com/tsCeK.png
Tolle kleine App, ich habe einen Launcher erstellt und /usr/local/bin eingefügt, damit ich ihn überall von einem Terminal usw. aus verwenden kann. Launcher-Skript: #!/bin/bash cd /Applications/terminal-notifier.app/Contents/ MacOS ./terminal-notifier $*
Launcher ist hilfreich, wenn Sie es ein wenig ändern, funktioniert es mit zitiertem Text mit Leerzeichen: #!/bin/bash cd /Applications/terminal-notifier.app/Contents/MacOS ./terminal-notifier "$@"
Einfach zu verwenden. Funktioniert aber aus irgendeinem Grund nicht in Cronjobs. ich bekommesh: terminal-notifier: command not found
@Nabin hat der Benutzer, der den Cron ausführt, das brewbin-Verzeichnis in der `$PATH-Variablen? Standardmäßig geht das nicht...

Ich möchte der Antwort von @ grgarside nur eine Anmerkung hinzufügen, da ich weiß, dass viele Leute ein Benachrichtigungs-Popup haben möchten, das nur durch Klicken auf die Schaltfläche geschlossen werden kann.

Vergleich

Ich habe die Lösung für dich gefunden:

Es wurde tatsächlich durch eine Einstellung in den Systemeinstellungen gesteuert und nicht durch einen Parameter im geschriebenen Skript. Diese beiden Bilder sollten alles erklären

Danke @grgarside für die tolle Antwort.

Systemeinstellung

Beachten Sie, dass die spezifische App variieren wird. Script Editorist nur für Script Editor.appund osascript. In einem Service-Workflow ist es Automator Runner. Wenn es drinnen Automator.appist, ist es Automator.
Ich finde es ärgerlich, dass, wenn ich auf das Banner klicke, die Skript-Editor-Anwendung aufgerufen wird. Ich möchte, dass es beim Klicken einfach verschwindet, aber dieser Beitrag weist darauf hin, dass Sie den Mauszeiger darüber bewegen und mit dem Trackpad nach rechts wischen können, damit es leise verschwindet: osxdaily.com/2012/09/05/…
@JoshuaGoldberg Danke, dass du das hinzugefügt hast! Ich habe das eines Tages intuitiv herausgefunden, was ich an Mac OS X mag, es funktioniert so, wie Sie es erwarten :)
Der Versuch, den osascriptBefehl zu verwenden, funktionierte plötzlich nicht, weder in iTerm noch im Terminal, bis ich zu den Benachrichtigungseinstellungen für den Skripteditor ging und ihn von „Keine“ auf „Banner“ änderte!
Ich hatte zeitweise Probleme damit, den display notificationerfolgreich zum Laufen zu bringen; Manchmal würde es funktionieren, manchmal würde es nur still sein. Nach Monaten dieses frustrierenden Verhaltens entdeckte ich schließlich, dass es durch „Nicht stören “ verursacht wurde , das ich nach 20 Uhr aktivieren wollte. 🤦‍♂️
Das scheint nicht mehr zu funktionieren (Big Sur sowieso) ...

Sie können dies jetzt mit Growl2 ( erhältlich im App Store ) tun. Growl installieren und "OS X Benachrichtigungen" aktivieren (Screenshot)

Geben Sie hier die Bildbeschreibung ein

Außerdem müssen Sie GrowlNotify für ein Befehlszeilentool installieren, um Growl-Benachrichtigungen zu senden. Sie können dieses Tool kostenlos auf der Download-Seite herunterladen .

Sie können jetzt Growl-Benachrichtigungen über die Befehlszeile generieren, die an das Notification Center weitergeleitet werden. Zum Beispiel:

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

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass es derzeit anscheinend nicht möglich ist, das Anwendungssymbol zu ändern.

Netter Ansatz, besonders wenn Growl bereits installiert ist.
Ich denke, Sie können die Option --icon path/to/icon.pngfür Symbole verwenden.
Veraltet/nicht mehr gepflegt? Das letzte Update war für Macos 10.9 Mavericks

Ich habe kürzlich terminal-notifier gegabelt, um ein Befehlszeilentool zu erstellen, um Benachrichtigungswarnungen (mit Aktionen) und Antworttypwarnungen anzuzeigen.

Ich verwende es mit meinen Shell-Skripten und Golang-Apps, um interaktive Antworten von Benutzern zu erhalten.

https://github.com/vjeantet/alerter

Geben Sie hier die Bildbeschreibung ein

Auch anscheinend veraltet / aufgegeben.
Sieht jetzt lebendig und wohlauf aus.

Die Lösung von @grgarside ist nett, aber sie ist anfällig für Skriptinjektionen, was ein großes Sicherheitsproblem darstellen kann, wenn dies verwendet wird, um z. B. den Inhalt von Protokolldateien oder ähnliches anzuzeigen.

Das sollte sicherer sein:

#!/bin/bash
X="$*" /usr/bin/osascript -e 'display notification system attribute "X"'
Das ist interessant, aber können Sie ein Szenario beschreiben, in dem ein Skript, das ich auf meinem System ausführe und das nur vom Benutzer ausführbar ist, anfällig für Skripteinschleusung ist?
Wenn Sie Benutzerinhalte anzeigen, die nicht von Ihnen stammen, sind Sie angreifbar. Zum Beispiel, wenn Sie dies auf einem System mit einem öffentlichen Webserver ausführen oder wenn eine App Zeichenfolgen protokolliert, die sie aus dem Netz erhalten hat, die Sie lesen und anzeigen, z. B. ein Browser, ein Mailprogramm oder ein Twitter-Client. Es könnte ein " haben, um die Zeichenfolge und die Anweisung zu beenden, dann Code zu haben und dann eine Zeichenfolge neu zu starten.
okay, das stimmt. Es fällt mir nur schwer, mir vorzustellen, jemals Inhalte aus Webformularen in meine Benachrichtigungen einzufügen, aber Ihr Punkt ist erledigt.
Nun, vielleicht möchten Sie einfach so etwas sagen, I have a "laser"ohne dass Ihnen gesagt wird, dass Sie einen Syntaxfehler haben, indem Sie Ihre „Wörter“ „zitieren“. Mit Escape können Sie:script 'I have a "laser"'
Stimmen Sie zu, weil es immer gut ist, die Sicherheit im Auge zu behalten. Jemand könnte Lösungen kopieren und sie auf eine Weise verwenden, die die Person, die die Lösung postet, nicht in Betracht gezogen hat.
Ich habe nur damit gespielt; diese Redewendung scheint nur einem Zitat zu entkommen. Gibt es eine "globale" Version?
@EdwardFalk der Substitution fehlte ein Schrägstrich. Sollte jetzt funktionieren.
Wenn Sie escaping verwenden möchten, müssen Sie auch \ -> \\ escapen, sonst wird \" zu \\" und Sie können ausbrechen. Ich habe das Beispiel geändert, um stattdessen eine Umgebungsvariable zu verwenden.

(Dies ist eine alternative Implementierung, die auf der hervorragenden Antwort von @grgarside basiert.)

AppleScript kann direkt interpretiert werden, indem osascriptdie Shebang-Zeile eingefügt wird.

#!/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

Speichern Sie dies notifyirgendwo in Ihrem Pfad, zB , /usr/local/bin/notifyund machen Sie es ausführbar ( chmod +x notify). Es akzeptiert eine Nachricht und einen optionalen Titel. Wenn eines von ihnen Leerzeichen enthält, schließen Sie es in Anführungszeichen ein, damit die Shell es als ein einzelnes Argument interpretiert.

$ notify "Lorem ipsum dolor sit amet" "Testing Notifications"
Dadurch werden die Injektionsangriffe vermieden, für die alle anderen Antworten anfällig sind
Schönes Skript, danke! Beachten Sie, dass "notify" in einigen Befehlen (wie meinem, tcsh) ein integrierter Shell-Befehl ist, sodass Sie möglicherweise einen anderen Namen verwenden müssen, wie ich es getan habe.
Gibt es eine Möglichkeit, die Benachrichtigung festzuhalten, sodass zum Schließen ein Klick erforderlich ist?
@CraigS.Anderson - eine der anderen Antworten (von Vic Jang) gibt an, dass dies durch die Systemeinstellungen des Benutzers bestimmt wird (unter Benachrichtigungen> Skript-Editor). Mir ist kein Skript-Weg bekannt, um das eine oder andere zu tun.

Da Growl nicht kostenlos ist und Terminal-Notifier auf Systemen vor 10.8 nicht verfügbar ist, neige ich dazu, coconutDialog zu verwenden . Es ist kostenlos und Open Source, sodass Sie es wahrscheinlich auch zusammen mit Ihren Skripten verteilen können.

Wenn Sie nicht viele Anpassungen benötigen, können Sie auch AppleScripts verwenden, display notificationdie Sie auch von der Shell aus aufrufen können, wie andere bereits erwähnt haben.

Beachten Sie jedoch, dass AppleScript doppelte Anführungszeichen zu erfordern scheint. Wenn Sie also Variablen benötigen, funktioniert dies nicht :

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

Sie müssen doppelte Anführungszeichen mit Escapezeichen verwenden. Das ist hässlich , funktioniert aber :

osascript -e "display notification \"$text\" with title \"$title\""
Das funktioniert auch:osascript -e 'display notification "Lorem ipsum dolor sit amet" with title "Title"'
Auch veraltet. Link liefert "Hier gibt es keine GitHub Pages-Site."

Hier ist ein cooles, das ich in einem Ruby-Skript unter OS X verwende (damit ich ein Skript starten und ein Update erhalten kann, auch nachdem ich das Fenster verlassen habe):

cmd = %Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
system ( cmd )
wow ... also ist die Kette so etwas wie User -> Ruby -> Shell -> AppleScript -> Objective-C -> Assembly -> CPU?
Ich komme so spät, aber fürs Protokoll, der Einfachheit halber habe ich einen LISP-Wrapper für den Ruby-Befehl geschrieben und ihn mit den mechanischen Armen eines dieser riesigen P-5000 Powered Work Loader-Exoskelette eingegeben, wie Ripley sie in Aliens trug .
@JohnSmith Genau aus diesem Grund lese ich alle Kommentare zu SE-Posts.
@johnsmith guter Punkt. Wir sollten dies natürlich in einen Docker-Container packen und es dann mit Kubernetes mithilfe einer CI/CD-Pipeline bereitstellen. :)

Eine Alternative:

Im .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"

Befehl verwenden:sys-notify "title" "message"

Offizielle Dokumentation

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

Kopieren Sie hier den Text, falls das Dokument verschoben oder entfernt wird.

Um eine Benachrichtigung anzuzeigen, geben Sie den Anzeigebenachrichtigungsbefehl mit einer anzuzeigenden Zeichenfolge an. Geben Sie optional Werte für die Parameter with title, subtitle und sound name an, um zusätzliche Informationen und einen akustischen Alarm bereitzustellen, wenn die Benachrichtigung angezeigt wird

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

HINWEIS

Nachdem Sie ein Skript zum Anzeigen einer Benachrichtigung verwendet haben, wird das Skript oder der Skript-Editor (wenn das Skript im Skript-Editor ausgeführt wird) zur Liste der benachrichtigenden Apps in Systemeinstellungen > Benachrichtigungen hinzugefügt. Dort können Sie Optionen konfigurieren, z. B. ob Benachrichtigungen als Warnungen oder Banner angezeigt werden sollen.

Durch Klicken auf die Schaltfläche „Anzeigen“ in einer Benachrichtigung im Benachrichtigungsstil wird die App geöffnet, die die Benachrichtigung angezeigt hat. Bei einer Skript-App löst die Aktion des erneuten Öffnens der App den Run-Handler des Skripts aus, was möglicherweise dazu führt, dass das Skript ein zweites Mal mit der Verarbeitung beginnt. Denken Sie daran, und fügen Sie gegebenenfalls Code zu Ihrem Skript hinzu, um dieses Szenario zu handhaben.

Danke, das war genau das, was ich für einige Benutzerskripte brauchte. Ich habe eine leichte Änderung vorgenommen, um einen Untertitel und Ton hinzuzufügen. Wenn kein Wert angegeben wird, wird er ignoriert.

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"

Verwenden Sie für den Sound einen Sounddateinamen ohne die Erweiterung aus /System/Library/Sounds. Um beispielsweise die Datei Ping.aiff zu verwenden, verwenden Sie Ping für $4

Wenn Sie klebrige Benachrichtigungen wünschen (Vic Jangs Kommentar scheint zumindest in Big Sur nicht mehr zu funktionieren), verwenden Sie hier eine Art Dialog statt Benachrichtigung:

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

Sie könnten also einen machen display notificationund dann mit dem Dialog weitermachen.

Auch Alerter macht Sticky.

$ brew install alerter
$ alerter -message "hi"
Gute Lösung, und Sie können verhindern , dass dialogIhr Terminal blockiert wird, indem Sie im Hintergrund laufen:osascript -e 'display dialog "Lorem ipsum dolor sit amet" with title "Title"' &