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

305

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

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

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

Натан Гринштейн
источник

Ответы:

428

С Mavericks и более поздними версиями вы можете сделать это, используя «экранное уведомление» AppleScript:

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

                          

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

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

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

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

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

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

    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
Grg
источник
9
@ceilingcat Это AppleScript. Чтобы запустить его в Терминале, используйте osascript (см. Ответ).
grg
8
Единственная проблема в display notificationтом, что когда вы нажимаете на нее, появляется диалог открытия файла.
ɹoƃı
7
Можно ли заставить всплывающее окно notificatiop существовать вечно (без автоматического скрытия через N секунд) до тех пор, пока пользователь не щелкнет явно?
Шридхар Ратнакумар
25
Дамы и господа, после часа исследований во всемирной паутине я выяснил, как оставить окно уведомлений, пока пользователь не закроет его! На самом деле это контролировалось настройкой в ​​System Preference, а не каким-либо параметром в написанном скрипте. Эти два изображения должны объяснить все это i.imgur.com/cNOqFyX.jpg i.imgur.com/i8oyoan.jpg Удачи, ребята, и спасибо @grgarside за отличный ответ.
Вик Джанг
4
Обратите внимание, что текст должен быть в двойных кавычках. Одиночные кавычки не работают. Так что если вам нужна переменная в тексте, вы не можете писать "display ... '$mytext' ...", но нужно спасся двойные кавычки: "display notification \"$mytext\" ...".
mivk 12.12.15
93

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

Из README:

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

В настоящее время он упакован в пакет приложений, потому NSUserNotificationчто не работает из «Основного инструмента». радар: // 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
Натан Гринштейн
2
Отличное небольшое приложение, я создал модуль запуска и поместил в / usr / local / bin, чтобы я мог использовать его в любом месте с терминала и т. Д. Сценарий запуска: #! / Bin / bash cd /Applications/terminal-notifier.app/Contents/ MacOS ./terminal-notifier $ *
Йоханандрен
4
Панель запуска полезна, если ее немного изменить, она работает с цитируемым текстом с пробелами: #! / Bin / bash cd /Applications/terminal-notifier.app/Contents/MacOS ./terminal-notifier "$ @"
Redbeard
27

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

сравнение

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

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

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

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

Вик Джанг
источник
5
Обратите внимание, что конкретное приложение будет отличаться. Script Editorтолько для Script Editor.appи osascript. В рабочем процессе службы это так Automator Runner. Когда внутри Automator.app, это Automator.
CDE
1
Меня раздражает, что если я нажимаю на баннер, он вызывает приложение Script Editor. Я бы хотел, чтобы он просто исчезал при нажатии, но в этом сообщении указывается, что вы можете навести на него курсор и провести пальцем по трекпаду
Джошуа Голдберг,
@JoshuaGoldberg Спасибо за добавление этого! Однажды я понял это интуитивно, и это одна вещь, которая мне нравится в Mac OS X: она работает так, как вы ожидаете, что она работает :)
Вик Джанг
22

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

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

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

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

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

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

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

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

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

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

https://github.com/vjeantet/alerter

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

vjeantet
источник
1
Также, видимо, устарела / заброшена.
Симус
15

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

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

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

Поскольку Growl не является бесплатным, а терминал-уведомитель недоступен в системах до 10.8, я склонен использовать CocoaDialog . Это бесплатный и открытый исходный код, поэтому вы также можете распространять его вместе со своими сценариями.

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

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

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

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

osascript -e "display notification \"$text\" with title \"$title\""
mivk
источник
Это также работает:osascript -e 'display notification "Lorem ipsum dolor sit amet" with title "Title"'
MikeSchinkel
Также не рекомендуется. Ссылка приводит к тому, что «здесь нет сайта GitHub Pages».
Симус
11

(Это альтернативная реализация, основанная на превосходном ответе @ 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"
Стив
источник
Это позволяет избежать инъекционных атак, которым подвержены все остальные ответы
Нил Мэйхью
7

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

cmd = %Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
system ( cmd )
JayCrossler
источник
2
вау ... так что цепочка что-то вроде User -> Ruby -> Shell -> AppleScript -> Objective-C -> Assembly -> CPU?
иконоборчество
5

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

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

ronald8192
источник
5

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

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

Копирование текста здесь, в случае, если документ перемещен или удален.

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

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

НОТА

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

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

nishanths
источник
1

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

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 доллара.

Кевин Мейсон
источник