Jak mogę uruchomić powiadomienie w Centrum powiadomień ze skryptu AppleScript lub skryptu powłoki?

305

Chciałbym móc korzystać z funkcji Centrum powiadomień 10.8 w skryptach AppleScript i skryptach powłoki, które piszę.

Czy istnieje wbudowane polecenie lub biblioteka innej firmy, której można używać ze skryptu AppleScript lub powłoki?

Najlepiej byłoby kontrolować rodzaj i ikonę powiadomienia, ale doceniona byłaby nawet możliwość uruchomienia podstawowego banera z ikoną giełdową (ale tekstem niestandardowym).

Nathan Greenstein
źródło

Odpowiedzi:

428

W Mavericks i nowszych wersjach możesz to zrobić za pomocą „powiadomienia ekranowego” AppleScript:

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

                          

To wszystko - dosłownie takie proste! Brak 3 rd biblioteki -party lub aplikacje wymagane i jest całkowicie przenośny do użytku w innych systemach. 10.9 powiadomienie u góry, 10.10 DP na środku, 10.10 na dole.

AppleScript można uruchomić z powłoki za pomocą / usr / bin / osascript:

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

Możesz także dostosować alert, dodając…

  • podtytuł

    Dołącz „podtytuł”, a następnie ciąg lub zmienną zawierającą podtytuł.

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

    Powyższy przykład generuje następujące powiadomienie:

  • dźwięk

    Dołącz „nazwę dźwięku”, a następnie nazwę dźwięku, który będzie odtwarzany wraz z powiadomieniem.

    display notification "message" sound name "Sound Name"

    Prawidłowe nazwy dźwięków to nazwy dźwięków znajdujących się w…

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

Powiadomienia o opublikowaniu można zapakować jako skrypt wiersza polecenia. Poniższy kod można uruchomić w Terminalu i doda skrypt do / usr / local / bin (musi istnieć, dodać do $ PATH) o nazwie notify.

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

Jest to skrypt, który powyżej doda, aby powiadomić.

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

Teraz, aby wyświetlić powiadomienie:

notify Lorem ipsum dolor sit amet
sleep 5; notify Slow command finished
grg
źródło
9
@ceilingcat To jest AppleScript. Aby uruchomić go w terminalu, użyj osascript (patrz odpowiedź).
grg
8
Jedynym problemem display notificationjest to, że po kliknięciu pojawia się okno dialogowe otwierania pliku.
ƃoƃı
7
Czy jest możliwe, aby wyskakujące powiadomienie istniało wiecznie (nie ukrywa się automatycznie po N sekundach), dopóki użytkownik nie kliknie go wyraźnie?
Sridhar Ratnakumar
25
Panie i panowie! Po godzinie śledztwa w Internecie dowiedziałem się, jak pozostawić okno powiadomień, dopóki użytkownik nie je odrzuci! W rzeczywistości był kontrolowany przez ustawienie w Preferencjach systemowych, a nie przez jakiś parametr w napisanym skrypcie. Te dwa obrazy powinny to wszystko wyjaśnić i.imgur.com/cNOqFyX.jpg i.imgur.com/i8oyoan.jpg Miłej zabawy i dziękuję @grgarside za świetną odpowiedź.
Vic Jang,
4
Pamiętaj, że tekst musi być w cudzysłowie. Pojedyncze cytaty nie działają. Więc jeśli potrzebujesz zmiennej w tekście, nie można napisać "display ... '$mytext' ...", ale potrzeba uciekł cudzysłowów: "display notification \"$mytext\" ...".
mivk
93

terminal-notifier

Z pliku README:

terminal-notifier to narzędzie wiersza polecenia do wysyłania powiadomień użytkowników systemu Mac OS X, które są dostępne w systemie Mac OS X 10.8.

Obecnie jest pakowany jako pakiet aplikacji, ponieważ NSUserNotificationnie działa z „narzędzia Foundation”. radar: // 11956694

Narzędzie to będzie używane przez Kickera do pokazywania statusu poleceń wykonywanych z powodu zmian w systemie plików. (v3.0.0)

Pobieranie

Wbudowane pliki binarne, podpisane kodem i gotowe do użycia, są dostępne w sekcji pobierania .

Stosowanie

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

Aby użyć terminal-notifier, musisz wywołać plik binarny w pakiecie aplikacji.

Pierwszy argument określa „grupę”, do której należy powiadomienie. W przypadku dowolnej „grupy” zostanie wyświetlone tylko jedno powiadomienie, zastępujące wcześniej opublikowane powiadomienia. Przykładami są: identyfikator procesu nadawcy, aby określić zakres powiadomień za pomocą unikalnego procesu lub bieżący katalog roboczy, aby określić zakres powiadomień za pomocą projektu.

Drugi i trzeci argument opisują samo powiadomienie i są odpowiednio jego „tytułem” i „komunikatem”. Na przykład, aby przekazać użytkownikowi powiadomienie o nadawcy, możesz podać nazwę nadawcy jako tytuł.

Czwarty i ostatni argument jest opcjonalny. Określa, która aplikacja powinna zostać aktywowana, gdy użytkownik kliknie powiadomienie. Domyślnie spowoduje to aktywację Terminal.app, aby zamiast tego uruchomić inną aplikację, podaj identyfikator pakietu aplikacji. Na przykład, aby uruchomić Safari.app użycie: com.apple.Safari.

Steve Moser
źródło
Słodka, świetna biblioteka! Chciałbym zobaczyć, jak jest aktualizowany z kontrolą nad ikoną i alertem kontra banerem, ale zdecydowanie przydatny. Dzięki za link! i.imgur.com/tsCeK.png
Nathan Greenstein
2
Świetna mała aplikacja, stworzyłem program uruchamiający i umieściłem / usr / local / bin, aby móc go używać w dowolnym miejscu z terminala itp. Skrypt uruchamiający: #! / Bin / bash cd /Applications/terminal-notifier.app/Contents/ MacOS ./terminal-notifier $ *
johanandren
4
Launcher jest pomocny, jeśli go trochę zmienisz, działa z cytowanym tekstem ze spacjami: #! / Bin / bash cd /Applications/terminal-notifier.app/Contents/MacOS ./terminal-notifier "$ @"
Redbeard
27

Chcę tylko dodać notatkę do odpowiedzi @ grgarside, ponieważ wiem, że wiele osób chce mieć okienko z powiadomieniem, które można usunąć tylko poprzez kliknięcie przycisku.

Porównanie

Znalazłem dla ciebie rozwiązanie:

W rzeczywistości był kontrolowany przez ustawienie w Preferencjach systemowych, a nie przez jakiś parametr w napisanym skrypcie. Te dwa obrazy powinny to wszystko wyjaśnić

Dzięki @grgarside za świetną odpowiedź.

Preferencje systemowe

Vic Jang
źródło
5
Pamiętaj, że konkretna aplikacja będzie się różnić. Script Editorjest tylko dla Script Editor.appi osascript. W przepływie pracy usługi jest to Automator Runner. W środku Automator.appjest Automator.
cde
1
Uważam, że denerwujące jest to, że kliknięcie Banera powoduje wyświetlenie aplikacji Script Editor. Chciałbym, aby po prostu zniknął po kliknięciu, ale ten post wskazuje, że możesz najechać na niego myszką
Joshua Goldberg
@JoshuaGoldberg Dziękujemy za dodanie tego! Przekonałem się, że któregoś dnia intuicyjnie, co podoba mi się w Mac OS X, działa tak, jak się spodziewasz :)
Vic Jang
22

Możesz to teraz zrobić za pomocą Growl2 ( dostępnego w App Store ). Zainstaluj Growl i włącz „Powiadomienia OS X” (zrzut ekranu)

wprowadź opis zdjęcia tutaj

Ponadto musisz zainstalować GrowlNotify dla narzędzia wiersza polecenia, aby wysyłać powiadomienia Growl. Możesz pobrać to narzędzie za darmo na stronie pobierania .

Możesz teraz generować powiadomienia Growl z wiersza poleceń, które zostaną przesłane do Centrum powiadomień. Na przykład:

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

wprowadź opis zdjęcia tutaj

Pamiętaj, że obecnie zmiana ikony aplikacji nie wydaje się możliwa.

Gerry
źródło
1
Ładne podejście, zwłaszcza jeśli growl jest już zainstalowany.
Besi
1
Myślę, że możesz użyć tej opcji --icon path/to/icon.pngdla ikon.
Czy
Przestarzałe / już nie utrzymywane? Ostatnia zmiana była dla MacOS 10.9 Mavericks
Seamus
15

Niedawno rozwidliłem terminal-notifier, aby zbudować narzędzie wiersza polecenia do wyświetlania alertów powiadomień (z działaniami) i alertów typu odpowiedzi.

Używam go ze skryptami powłoki i aplikacjami golang, aby uzyskać interaktywne odpowiedzi od użytkowników.

https://github.com/vjeantet/alerter

wprowadź opis zdjęcia tutaj

vjeantet
źródło
1
Również najwyraźniej przestarzałe / porzucone.
Seamus
15

@grgarside „s rozwiązanie jest ładny, ale jest podatny na wstrzyknięcie skryptu, który może być poważnym problemem bezpieczeństwa, kiedy ta służy do wyświetlania np dziennika zawartość pliku lub coś podobnego.

To powinno być bezpieczniejsze:

#!/bin/bash
X="$*" /usr/bin/osascript -e 'display notification system attribute "X"'
Archimedix
źródło
to interesujące, ale czy możesz opisać scenariusz, w którym skrypt uruchamiany w moim systemie, który jest wykonywalny tylko przez użytkownika, jest podatny na wstrzyknięcie skryptu?
iconoclast,
1
Jeśli wyświetlasz treści użytkownika, które nie pochodzą od ciebie, jesteś podatny na ataki. Na przykład, jeśli uruchamiasz to w systemie z publicznym serwerem internetowym lub gdy niektóre aplikacje rejestrują ciągi znaków, pobiera je z sieci, którą czytasz i wyświetlasz, np. Przeglądarka, program pocztowy lub klient Twitter. Może zawierać „, aby zakończyć ciąg i instrukcję, a następnie mieć kod, a następnie ponownie uruchomić ciąg.
Archimedix,
okej, to prawda. po prostu trudno mi sobie wyobrazić umieszczanie treści z formularzy internetowych w moich powiadomieniach, ale twoja uwaga jest słuszna.
iconoclast,
1
Cóż, może chciałbyś po prostu powiedzieć coś takiego, I have a "laser"bez informowania cię, że masz błąd składniowy przez „zacytowanie” swoich „słów”. Dzięki ucieczce możesz:script 'I have a "laser"'
Archimedix,
1
Zwróć uwagę, ponieważ zawsze warto pamiętać o bezpieczeństwie. Ktoś mógł skopiować rozwiązania makaronu i wykorzystać je w sposób, którego nie zastanawiał się nad tym autor.
Edward Falk
13

Ponieważ Growl nie jest darmowy, a terminal-notifier nie jest dostępny w systemach starszych niż 10.8, zwykle używam cocoaDialog . Jest darmowy i open source, więc prawdopodobnie możesz również dystrybuować wraz ze swoimi skryptami.

Jeśli nie potrzebujesz dużo dostosowywania, możesz także użyć AppleScript, display notificationktóry możesz również wywołać z powłoki, jak już wspomnieli inni.

Ale uwaga, że ​​AppleScript wydaje się wymagać podwójnych cudzysłowów. Więc jeśli potrzebujesz zmiennych, to nie zadziała :

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

Będziesz musiał użyć podwójnych cudzysłowów. To jest brzydkie, ale działa :

osascript -e "display notification \"$text\" with title \"$title\""
mivk
źródło
Działa to również:osascript -e 'display notification "Lorem ipsum dolor sit amet" with title "Title"'
MikeSchinkel,
Przestarzałe również. Link daje „Nie ma tu strony GitHub”.
Seamus
11

(Jest to alternatywna implementacja oparta na doskonałej odpowiedzi @ grgarside).

AppleScript można interpretować bezpośrednio, wstawiając osascriptlinię 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

Zapisz to jako notifygdzieś na swojej ścieżce, np. /usr/local/bin/notifyI uczyń ją wykonywalną ( chmod +x notify). Akceptuje wiadomość i opcjonalny tytuł. Jeśli którykolwiek z nich ma spację, zawiń go w cudzysłów, aby powłoka zinterpretowała go jako pojedynczy argument.

$ notify "Lorem ipsum dolor sit amet" "Testing Notifications"
Steve
źródło
Pozwala to uniknąć ataków iniekcyjnych, na które narażone są wszystkie pozostałe odpowiedzi
Neil Mayhew
7

Oto fajny, którego używam w skrypcie ruby ​​w systemie OS X (dzięki czemu mogę uruchomić skrypt i uzyskać aktualizację nawet po przełączeniu się z okna):

cmd = %Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
system ( cmd )
JayCrossler
źródło
2
wow ... więc łańcuch przypomina coś Użytkownik -> Ruby -> Shell -> AppleScript -> Objective-C -> Assembly -> CPU?
iconoclast,
5

Alternatywa:

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

Użyj polecenia: sys-notify "title" "message"

ronald8192
źródło
5

Oficjalna dokumentacja

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

Kopiowanie tekstu tutaj, w przypadku przeniesienia lub usunięcia dokumentu.

Aby wyświetlić powiadomienie, podaj polecenie wyświetlania powiadomienia z ciągiem do wyświetlenia. Opcjonalnie podaj wartości parametrów z tytułem, podtytułem i nazwą dźwięku, aby zapewnić dodatkowe informacje i alarm dźwiękowy, gdy pojawi się powiadomienie

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

UWAGA

Po użyciu skryptu do wyświetlenia powiadomienia skrypt lub edytor skryptów (jeśli skrypt jest uruchamiany z poziomu edytora skryptów) jest dodawany do listy aplikacji powiadamiających w Preferencjach systemowych> Powiadomienia. Tam możesz skonfigurować opcje, takie jak wyświetlanie powiadomień jako alertów lub banerów.

Kliknięcie przycisku Pokaż w powiadomieniu przypominającym alert powoduje otwarcie aplikacji, która wyświetliła powiadomienie. W przypadku aplikacji skryptowej czynność ponownego otwarcia aplikacji wyzwala moduł obsługi skryptu, co może spowodować, że skrypt zacznie przetwarzać się po raz drugi. Należy o tym pamiętać i w razie potrzeby dodać kod do skryptu, aby obsłużyć ten scenariusz.

nishanths
źródło
1

Dziękuję, właśnie tego potrzebowałem do niektórych skryptów użytkownika. Wprowadziłem niewielką modyfikację, aby dodać napisy i dźwięk. Jeśli wartość nie zostanie podana, zostanie zignorowana.

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"

Do dźwięku użyj nazwy pliku dźwiękowego bez rozszerzenia z / System / Library / Sounds. Na przykład, aby użyć pliku Ping.aiff, użyj polecenia Ping za 4 USD

Kevin Mason
źródło