I'd love to be able to take advantage of 10.8's Notification Center features in AppleScripts and shell scripts I write.

Is there a built-in command or a third-party library I can use from either an AppleScript or shell script?

Ideally the type and icon of the notification could be controlled, but even just the ability to trigger a basic banner with a stock icon (but custom text) would be appreciated.

11 Answers 11

up vote 386 down vote accepted

With Mavericks and later, you can do this using AppleScript's 'display notification':

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

                          

That's it—literally that simple! No 3rd-party libraries or apps required and is completely portable for use on other systems. 10.9 notification on the top, 10.10 DP in the middle, 10.10 on the bottom.

AppleScript can be run from the shell using /usr/bin/osascript:

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

You can also customise the alert further by adding…

  • a subtitle

    Append 'subtitle' followed by the string or variable containing the subtitle.

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

    The above example produces the following notification:

  • sound

    Append 'sound name' followed by the name of a sound that will be played along with the notification.

    display notification "message" sound name "Sound Name"
    

    Valid sound names are the names of sounds located in…

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

Posting notifications can be wrapped as a command-line script. The following code can be run in Terminal and will add a script to /usr/local/bin (must exist, add to $PATH) called notify.

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

This is the script that the above will add to notify.

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

Now to display a notification:

notify Lorem ipsum dolor sit amet
sleep 5; notify Slow command finished
  • 8
    @ceilingcat This is AppleScript. To run it in Terminal, use osascript (see answer). – grg May 2 '14 at 18:32
  • 8
    The only problem with display notification is that when you click on it, the open file dialog appears. – ɹoƃı Aug 13 '14 at 20:57
  • 7
    Is it possible to make the notificatiop popup exist forever (not auto-hide after N seconds) until explicitly clicked by the user? – Sridhar Ratnakumar Apr 1 '15 at 22:15
  • 21
    Ladies and gentlemen, after an hour of investigation on the world wide web, I have found out how to let the notification window stay until dismissed by user! It was actually controlled by a setting in System Preference, rather than some parameter in the script written. These two images should explain it all i.imgur.com/cNOqFyX.jpg i.imgur.com/i8oyoan.jpg Have fun guys, and thanks @grgarside for the great answer. – Vic Jang Nov 7 '15 at 0:31
  • 4
    Note that the text has to be in double quotes. Single quotes don't work. So if you need a variable in the text, you cannot write "display ... '$mytext' ...", but need escaped double quotes: "display notification \"$mytext\" ...". – mivk Dec 12 '15 at 11:14
up vote 84 down vote
+100

terminal-notifier

From the README:

terminal-notifier is a command-line tool to send Mac OS X User Notifications, which are available in Mac OS X 10.8.

It is currently packaged as an application bundle, because NSUserNotification does not work from a ‘Foundation tool’. radar://11956694

This tool will be used by Kicker to show the status of commands which are executed due to filesystem changes. (v3.0.0)

Download

Prebuilt binaries, which are code-signed and ready to use, are available from the downloads section.

Usage

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

In order to use terminal-notifier, you have to call the binary inside the app bundle.

The first argument specifies the ‘group’ a notification belongs to. For any ‘group’ only one notification will ever be shown, replacing previously posted notifications. Examples are: the sender’s process ID to scope the notifications by a unique process, or the current working directory to scope notifications by a project.

The second and third arguments describe the notification itself and are its ‘title’ and ‘message’ respectively. For example, to communicate the sender of a notification to the user, you could specify the sender’s name as the title.

The fourth and last argument is an optional one. It specifies which application should be activated when the user clicks the notification. By default this will activate Terminal.app, to launch another application instead specify the application’s bundle identifier. For example, to launch Safari.app use: com.apple.Safari.

  • Sweet, a great library! Would love to see it updated with control over the icon and alert vs banner, but definitely useful. Thanks for the link! i.imgur.com/tsCeK.png – Nathan Greenstein Jul 25 '12 at 20:27
  • 2
    Great little app, I created a launcher and put in /usr/local/bin so that I can use it anywhere from a terminal etc. Launcher script: #!/bin/bash cd /Applications/terminal-notifier.app/Contents/MacOS ./terminal-notifier $* – johanandren Jul 26 '12 at 7:13
  • 4
    Launcher is helpful, if you change it a bit it works with quoted text with spaces: #!/bin/bash cd /Applications/terminal-notifier.app/Contents/MacOS ./terminal-notifier "$@" – Redbeard Jul 31 '12 at 1:34

I just want to add a note to @grgarside's answer, because I know many people want to have a notification popup that can only be dismissed by button click.

Comparison

I have found the solution for you:

It was actually controlled by a setting in System Preference, rather than some parameter in the script written. These two images should explain it all

Thanks @grgarside for the great answer.

System Preference

  • 3
    Note that the specific app will vary. Script Editor is only for Script Editor.app and osascript. In a service workflow, it's Automator Runner. When inside Automator.app, it's Automator. – cde Mar 22 '16 at 19:29
  • 1
    I find it annoying that if I click on the Banner, it brings up the Script Editor application. I'd like for it to just disappear on click, but this post points out you can hover over it and trackpad-swipe right to make it go away quietly: osxdaily.com/2012/09/05/… – Joshua Goldberg Mar 31 '16 at 14:24
  • @JoshuaGoldberg Thanks for adding that! I found that out intuitively one day, which is one thing I like about Mac OS X, it works the way you expect it do work :) – Vic Jang Apr 1 '16 at 7:46

You can now do this with Growl2 (available from the App Store). Install Growl and enable "OS X Notifications" (screenshot)

enter image description here

Additionally, you'll need to install GrowlNotify for a command-line tool to send Growl notifications. You can download this tool for free on the Download page.

You can now generate Growl notifications from the command line, which will be forwarded to the Notification Center. For example:

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

enter image description here

Note that it currently doesn't seem possible to change the application icon.

  • 1
    Nice approach especially if growl is installed already. – Besi Oct 25 '12 at 12:34
  • 1
    I think you might be able to use the option --icon path/to/icon.png for icons. – Will Feb 12 '14 at 17:37

I recently forked terminal-notifier to build a command line tool to display notification Alerts (with actions) and Reply Type Alerts.

I use it with my shell scripts and golang apps to get interactive answers from users.

https://github.com/vjeantet/alerter

enter image description here

@grgarside's solution is nice, but it is vulnerable to script injection, which can be a major security issue when this is used to e.g. display log file contents or something similar.

This should be safer:

#!/bin/bash
X="$*" /usr/bin/osascript -e 'display notification system attribute "X"'
  • this is interesting, but can you describe a scenario where a script I run on my system that is only user-executable is vulnerable to script injection? – iconoclast Dec 18 '15 at 15:49
  • 1
    If you display user content that is not from you, you are vulnerable. For example if you run this on a system with a public web server, or when some app logs strings it got from the net which you read and display, e.g. a browser, mail program or a Twitter client. It could have a " to end the string and statement, then have code and then restart a string. – Archimedix Dec 18 '15 at 21:54
  • okay, that's true. it's just hard for me to imagine ever putting content from web forms into my notifications, but your point is taken. – iconoclast Dec 18 '15 at 23:30
  • 1
    Well, maybe you'd just like to say something like I have a "laser" without being told you're having a syntax error by "quoting" your "words". With escaping, you can: script 'I have a "laser"' – Archimedix Dec 19 '15 at 8:47
  • 1
    Upvote because it's always good to keep security in mind. Someone could copy-pasta solutions and use them in ways the person posting the solution hadn't considered. – Edward Falk Jul 22 '16 at 19:06

Since Growl is not free, and terminal-notifier is not available on pre-10.8 systems, I tend to use cocoaDialog. It is free and open source, so you can probably also distribute along with your scripts.

If you don't need a lot of customization, you can also use AppleScript's display notification which you can also call from the shell as others have already mentioned.

But beware that AppleScript seems to require double-quotes. So if you need variables, this will not work:

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

You will have to use escaped double-quotes. This is ugly but works:

osascript -e "display notification \"$text\" with title \"$title\""
  • This also works: osascript -e 'display notification "Lorem ipsum dolor sit amet" with title "Title"' – MikeSchinkel May 12 '17 at 6:11

Here's a cool one that I use in a ruby script on OS X (so that I can start a script and get an update even after toggling away from the window):

cmd = %Q|osascript -e 'display notification "Server was reset" with title "Posted Update"'|
system ( cmd )
  • 2
    wow... so the chain is something like User -> Ruby -> Shell -> AppleScript -> Objective-C -> Assembly -> CPU? – iconoclast Dec 18 '15 at 15:52

(This is an alternative implementation based on @grgarside's excellent answer.)

AppleScript can be interpreted directly by putting osascript in the shebang line.

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

Save this as notify somewhere in your path, e.g., /usr/local/bin/notify, and make it executable (chmod +x notify). It accepts a message and an optional title. If either has whitespace, wrap it in quotes so the shell interprets it as a single argument.

$ notify "Lorem ipsum dolor sit amet" "Testing Notifications"
  • This avoids the injection attacks that all the other answers are vulnerable to – Neil Mayhew Aug 10 at 16:22

Official documentation

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

Copying the text here, in case the document is moved or removed.

To show a notification, provide the display notification command with a string to display. Optionally, provide values for the with title, subtitle, and sound name parameters to provide additional information and an audible alert when the notification appears

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

NOTE

After using a script to display a notification, the script or Script Editor (if the script is run from within Script Editor) is added to the list of notifying apps in System Preferences > Notifications. There, you can configure options, such as whether to display notifications as alerts or banners.

Clicking the Show button in an alert-style notification opens the app that displayed the notification. For a script app, the action of opening the app again triggers the run handler of the script, potentially causing the script to begin processing a second time. Keep this in mind, and add code to your script to handle this scenario, if appropriate.

An alternative:

In .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 command: sys-notify "title" "message"

  • 2
    downvoter please explain – ronald8192 Oct 25 '17 at 2:16
  • If this is an improvement on the accepted answer from 4 years previously, you need to explain that. – Neil Mayhew Aug 10 at 16:25

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.