Как я могу активировать уведомление Центра уведомлений из сценария AppleScript или оболочки?

Я хотел бы иметь возможность использовать преимущества Центра уведомлений 10.8 в сценариях AppleScript и сценариях оболочки, которые я пишу.

Есть ли встроенная команда или сторонняя библиотека, которую я могу использовать из сценария AppleScript или оболочки?

В идеале можно управлять типом и значком уведомления, но приветствуется даже возможность запуска базового баннера со стандартным значком (но настраиваемым текстом).

Ответы (13)

В Mavericks и более поздних версиях вы можете сделать это с помощью «отображения уведомления» AppleScript:

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

                          

Вот и все — буквально так просто! Никаких сторонних библиотек или приложений не требуется, и он полностью переносим для использования в других системах. Уведомление 10.9 сверху, 10.10 DP посередине, 10.10 снизу.

AppleScript можно запустить из оболочки с помощью /usr/bin/osascript:

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

Вы также можете дополнительно настроить оповещение, добавив…

  • подзаголовок

    Добавьте 'subtitle', а затем строку или переменную, содержащую подзаголовок.

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

    В приведенном выше примере создается следующее уведомление:

  • звук

    Добавьте «название звука», а затем название звука, который будет воспроизводиться вместе с уведомлением.

    display notification "message" sound name "Sound Name"
    

    Допустимые названия звуков — это названия звуков, расположенных в…

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

Уведомления о публикации можно оформить как сценарий командной строки. Следующий код можно запустить в Терминале, и он добавит скрипт в /usr/local/bin (должен существовать, добавьте в $PATH) с именем notify.

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

Это скрипт, который выше будет добавлен для уведомления.

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

Теперь, чтобы отобразить уведомление:

notify Lorem ipsum dolor sit amet
sleep 5; notify Slow command finished
Каков путь display? У меня есть Mavericks, но я не могу найти его. Спасибо!
@ceilingcat Не могли бы вы уточнить, что вы имеете в виду? Что не работает?
Я получил -bash: display: command not foundМой путь довольно странный, поэтому было бы неплохо точно знать, где displayон находится.
@ceilingcat Это AppleScript. Чтобы запустить его в Терминале, используйте osascript (см. ответ).
Единственная проблема display notificationзаключается в том, что при нажатии на нее появляется диалоговое окно открытия файла.
Можно ли сделать так, чтобы всплывающее окно с уведомлением существовало вечно (не автоматически скрывалось через N секунд) до тех пор, пока пользователь явно не нажмет?
Как добавить ограничение по времени для отображения уведомления на экране?
Пара вопросов - 1. Можно как-нибудь добавить определенные действия при клике на уведомление? Скажем, я хочу запустить определенный сценарий оболочки. Я на Yosemite, и он запускает файловый браузер. 2. Как мне настроить уведомление с дополнительными параметрами, например, показать кнопку сбоку при наведении на него, например, что происходит, когда следующая песня iTunes автоматически воспроизводится и появляется уведомление, показывающее эту песню, или когда вы нажимаете на уведомление, когда вы есть новое сообщение, появляются два варианта - Отправить и Отменить?
Ничто из того, что я нашел, не указывает на то, что есть способ управлять действием (что происходит, когда вы нажимаете на уведомление). macosxautomation.com/mavericks/notifications/01.html удобен, к вашему сведению.
Уважаемые дамы и господа, после часа поисков во всемирной паутине я обнаружил, как сделать так, чтобы окно уведомлений не закрывалось пользователем! На самом деле это контролировалось настройкой в ​​Системных настройках, а не каким-то параметром в написанном скрипте. Эти два изображения должны все объяснить i.imgur.com/cNOqFyX.jpg i.imgur.com/i8oyoan.jpg Получайте удовольствие, ребята, и спасибо @grgarside за отличный ответ.
Обратите внимание, что текст должен быть заключен в двойные кавычки. Одинарные кавычки не работают. Поэтому, если вам нужна переменная в тексте, вы не можете писать "display ... '$mytext' ...", но вам нужны экранированные двойные кавычки: "display notification \"$mytext\" ...".
display notificationу меня не работает на El Capitan, хотя display alertработает нормально. В документации утверждается, что оба работают. Любое понимание этого?
Как упомянул Вик Джанг, но не объяснил четко, вы можете изменить настройки отображения уведомлений через «Системные настройки»> «Уведомления»> «Редактор сценариев»> изменить «Баннеры» на «Оповещения». Таким образом, вы можете по крайней мере нажать «Закрыть» вместо того, чтобы видеть диалоговое окно «Открыть файл», когда вы отклоняете уведомление.
@Dan Щелчок по уведомлению никогда не является действием закрытия, поэтому при нажатии запускается редактор сценариев. Вы можете закрыть баннер, проведя двумя пальцами по экрану при наведении на него курсора. Я могу рассмотреть альтернативы, если у меня будет время в какой-то момент.
пользовательское изображение для уведомления?
Похоже, sound nameбольше не позволяет воспроизводить пользовательские звуки ~/Library/Sounds. Кто-нибудь знает исправление? Использование macOS 10.13.2.
На Mac 11.2.3:zsh: command not found: display
@Alik Пожалуйста, прочитайте ответ, в частности: «AppleScript можно запустить из оболочки, используя /usr/bin/osascript»
Мне пришлось убить процесс «Центр уведомлений», который перезапускается автоматически, прежде чем уведомление начало появляться.

терминал-уведомитель

Из README:

terminal-notifier — это инструмент командной строки для отправки уведомлений пользователей Mac OS X, которые доступны в Mac OS X 10.8.

В настоящее время он упакован как пакет приложений, поскольку NSUserNotificationне работает из «инструмента Foundation». радар://11956694

Этот инструмент будет использоваться Kicker для отображения статуса команд, которые выполняются из-за изменений в файловой системе. (v3.0.0)

Скачать

Готовые двоичные файлы, подписанные кодом и готовые к использованию, доступны в разделе загрузок .

Применение

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

Чтобы использовать терминал-уведомитель, вы должны вызвать двоичный файл внутри пакета приложения.

Первый аргумент указывает «группу», к которой принадлежит уведомление. Для любой «группы» будет отображаться только одно уведомление, заменяющее ранее опубликованные уведомления. Примеры: идентификатор процесса отправителя, чтобы ограничить уведомления уникальным процессом, или текущий рабочий каталог, чтобы ограничить уведомления проектом.

Второй и третий аргументы описывают само уведомление и являются его «заголовком» и «сообщением» соответственно. Например, чтобы сообщить пользователю об отправителе уведомления, можно указать имя отправителя в качестве заголовка.

Четвертый и последний аргумент является необязательным. Он указывает, какое приложение должно быть активировано, когда пользователь щелкает уведомление. По умолчанию это активирует Terminal.app, чтобы запустить другое приложение вместо указания идентификатора пакета приложения. Например, для запуска Safari.app используйте: com.apple.Safari.

Мила, отличная библиотека! Хотелось бы, чтобы он был обновлен с контролем над значком и предупреждением против баннера, но определенно полезен. Спасибо за ссылку! i.imgur.com/tsCeK.png
Отличное маленькое приложение, я создал программу запуска и поместил ее в /usr/local/bin, чтобы использовать ее где угодно с терминала и т. д. Сценарий запуска: #!/bin/bash cd /Applications/terminal-notifier.app/Contents/ MacOS ./терминал-уведомитель $*
Лаунчер полезен, если его немного изменить, он работает с текстом в кавычках с пробелами: #!/bin/bash cd /Applications/terminal-notifier.app/Contents/MacOS ./terminal-notifier "$@"
Легко использовать. Но почему-то не работает в cronjobs. я осознаюsh: terminal-notifier: command not found
@Nabin есть ли у пользователя, запускающего cron, brewкаталог bin в переменной $PATH? По умолчанию не...

Я просто хочу добавить примечание к ответу @grgarside, потому что я знаю, что многие люди хотят иметь всплывающее уведомление, которое можно закрыть только нажатием кнопки.

Сравнение

Я нашел решение для вас:

На самом деле это контролировалось настройкой в ​​Системных настройках, а не каким-то параметром в написанном скрипте. Эти два изображения должны все объяснить

Спасибо @grgarside за отличный ответ.

Системные настройки

Обратите внимание, что конкретное приложение будет отличаться. Script Editorтолько для Script Editor.appи osascript. В рабочем процессе службы это Automator Runner. Когда внутри Automator.app, это Automator.
Меня раздражает, что если я нажму на баннер, откроется приложение Script Editor. Я бы хотел, чтобы он просто исчезал при нажатии, но в этом посте указано, что вы можете навести на него курсор и провести пальцем вправо по трекпаду, чтобы он исчез незаметно: osxdaily.com/2012/09/05/…
@JoshuaGoldberg Спасибо, что добавили это! Однажды я понял это интуитивно, что мне нравится в Mac OS X, она работает так, как вы ожидаете от нее :)
Попытка использовать osascriptкоманду внезапно перестала работать ни в iTerm, ни в терминале, пока я не зашел в настройки уведомлений для редактора сценариев и не изменил его с «Нет» на «Баннеры»!
У меня были периодические проблемы с display notificationуспешным запуском; иногда это работало, иногда просто молчало. После нескольких месяцев такого разочаровывающего поведения я наконец обнаружил, что это было вызвано режимом « Не беспокоить », который я планировал активировать после 8 вечера. 🤦‍♂️
Кажется, это больше не работает (во всяком случае, Биг Сур)...

Теперь вы можете сделать это с помощью Growl2 ( доступно в App Store ). Установите Growl и включите «Уведомления OS X» (скриншот)

введите описание изображения здесь

Кроме того, вам потребуется установить GrowlNotify для инструмента командной строки для отправки уведомлений Growl. Вы можете скачать этот инструмент бесплатно на странице загрузки .

Теперь вы можете создавать уведомления Growl из командной строки, которые будут перенаправлены в Центр уведомлений. Например:

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

введите описание изображения здесь

Обратите внимание, что в настоящее время изменить значок приложения не представляется возможным.

Хороший подход, особенно если гроул уже установлен.
Я думаю, вы могли бы использовать опцию --icon path/to/icon.pngдля значков.
Устарело/больше не поддерживается? Последнее обновление было для macos 10.9 mavericks

Недавно я разветвил terminal-notifier, чтобы создать инструмент командной строки для отображения предупреждений об уведомлениях (с действиями) и предупреждений о типе ответа.

Я использую его со своими сценариями оболочки и приложениями golang, чтобы получать интерактивные ответы от пользователей.

https://github.com/vjeantet/alerter

введите описание изображения здесь

Также, по-видимому, устарело / заброшено.
Сейчас выглядит живым и здоровым.

Решение @grgarside хорошее , но оно уязвимо для внедрения скриптов, что может быть серьезной проблемой безопасности, когда оно используется, например, для отображения содержимого файла журнала или чего-то подобного.

Это должно быть безопаснее:

#!/bin/bash
X="$*" /usr/bin/osascript -e 'display notification system attribute "X"'
это интересно, но можете ли вы описать сценарий, в котором скрипт, который я запускаю в своей системе и который может выполняться только пользователем, уязвим для внедрения скрипта?
Если вы показываете пользовательский контент, который не от вас, вы уязвимы. Например, если вы запускаете это в системе с общедоступным веб-сервером, или когда какое-то приложение регистрирует строки, которые оно получило из сети, которую вы читаете и отображаете, например, браузер, почтовая программа или клиент Twitter. Он может иметь ", чтобы закончить строку и оператор, затем иметь код, а затем перезапустить строку.
хорошо, это правда. мне просто трудно представить, что когда-нибудь я буду помещать контент из веб-форм в свои уведомления, но ваша точка зрения принята.
Ну, может быть, вы просто хотели бы сказать что-то вроде I have a "laser"того, что у вас синтаксическая ошибка, «цитируя» ваши «слова». С помощью побега вы можете:script 'I have a "laser"'
Голосуйте за, потому что всегда полезно помнить о безопасности. Кто-то может копировать решения и использовать их так, как человек, опубликовавший решение, не подумал.
Я просто играл с ним; эта идиома, кажется, избегает только одной цитаты. Есть "глобальная" версия?
@EdwardFalk в замене отсутствовала косая черта. Должно работать сейчас.
Если вы хотите использовать экранирование, вы также должны экранировать \ -> \\, иначе \" становится \\" и вы можете вырваться. Я изменил пример, чтобы вместо этого использовать переменную среды.

(Это альтернативная реализация, основанная на отличном ответе @grgarside.)

AppleScript можно интерпретировать напрямую, вставив osascriptстроку 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

Сохраните это как где- notifyнибудь в вашем пути, например, /usr/local/bin/notifyи сделайте его исполняемым ( chmod +x notify). Он принимает сообщение и необязательный заголовок. Если в любом из них есть пробелы, заключите его в кавычки, чтобы оболочка интерпретировала его как один аргумент.

$ notify "Lorem ipsum dolor sit amet" "Testing Notifications"
Это позволяет избежать инъекций, которым уязвимы все остальные ответы.
Хороший сценарий, спасибо! Обратите внимание, что «notify» — это встроенная команда оболочки в некоторых командах (например, моя, tcsh), поэтому вам может понадобиться использовать другое имя, как это сделал я.
Есть ли способ сделать уведомление липким, чтобы для его закрытия требовался щелчок?
@CraigS.Anderson - один из других ответов (от Вика Джанга) указывает, что это определяется Системными настройками пользователя (в разделе «Уведомления»> «Редактор сценариев»). Я не знаю скриптового способа сделать то или иное.

Поскольку Growl не является бесплатным, а terminal-notifier недоступен в системах до версии 10.8, я предпочитаю использовать CocoDialog . Это бесплатно и с открытым исходным кодом, так что вы, вероятно, также можете распространять его вместе со своими скриптами.

Если вам не нужно много настроек, вы также можете использовать AppleScript, display notificationкоторый вы также можете вызывать из оболочки, как уже упоминалось другими.

Но имейте в виду, что AppleScript требует двойных кавычек. Итак, если вам нужны переменные, это не сработает :

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

Вам придется использовать экранированные двойные кавычки. Это некрасиво, но работает :

osascript -e "display notification \"$text\" with title \"$title\""
Это также работает:osascript -e 'display notification "Lorem ipsum dolor sit amet" with title "Title"'
Также устарел. Ссылка дает «Здесь нет сайта GitHub Pages».

Вот классный вариант, который я использую в ruby-скрипте на OS X (чтобы я мог запустить скрипт и получить обновление даже после переключения из окна):

cmd = %Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
system ( cmd )
вау... так что цепочка выглядит примерно так: User -> Ruby -> Shell -> AppleScript -> Objective-C -> Assembly -> CPU?
С таким опозданием, но для протокола, для удобства я написал оболочку LISP для команды Ruby и набрал ее механическими руками одного из тех гигантских механических экзоскелетов P-5000 Powered Work Loader, какие носила Рипли в « Чужих ». .
@JohnSmith Именно поэтому я читаю все комментарии к сообщениям SE.
@johnsmith хорошее замечание. Мы, очевидно, должны обернуть это в док-контейнер, а затем развернуть его с помощью Kubernetes с использованием конвейера CI/CD. :)

Альтернатива:

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

Используйте команду:sys-notify "title" "message"

Официальная документация

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

Копируем сюда текст на случай, если документ будет перемещен или удален.

Чтобы отобразить уведомление, предоставьте команде отображения уведомления строку для отображения. При необходимости укажите значения для параметров with title, subtitle и sound name, чтобы предоставить дополнительную информацию и звуковой сигнал при появлении уведомления.

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

ПРИМЕЧАНИЕ

После использования сценария для отображения уведомления сценарий или редактор сценариев (если сценарий запускается из редактора сценариев) добавляется в список уведомляющих приложений в разделе «Системные настройки» > «Уведомления». Там вы можете настроить параметры, например, отображать ли уведомления в виде предупреждений или баннеров.

При нажатии кнопки «Показать» в уведомлении в виде предупреждения открывается приложение, в котором отображалось уведомление. Для приложения-скрипта действие повторного открытия приложения запускает обработчик запуска скрипта, что потенциально может привести к тому, что скрипт начнет обработку во второй раз. Имейте это в виду и добавьте в свой сценарий код для обработки этого сценария, если это необходимо.

Спасибо, это как раз то, что мне было нужно для некоторых пользовательских скриптов. Я сделал небольшую модификацию, добавив субтитры и звук. Если значение не указано, оно игнорируется.

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"

Для звука используйте имя звукового файла без расширения из /System/Library/Sounds. Например, чтобы использовать файл Ping.aiff, используйте Ping за 4 доллара.

Если вам нужны липкие уведомления (комментарий Вика Джанга, кажется, больше не работает, по крайней мере, в Big Sur), вот своего рода способ, используйте диалоговое окно вместо уведомления:

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

Таким образом, вы можете сделать один, display notificationа затем продолжить диалог.

Также оповещение делает липким.

$ brew install alerter
$ alerter -message "hi"
Хорошее решение, и вы можете предотвратить dialogблокировку вашего терминала, запустив в фоновом режиме:osascript -e 'display dialog "Lorem ipsum dolor sit amet" with title "Title"' &