Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

I'm running a series of commands on the command line that takes approximately twenty minutes to complete. I'd like to see some sort of notification on my Mac when these are finished so I don't need to monitor the terminal for when it finishes. Is there a way to do this?

$ svn update . && ant clean build start && *notify_me_somehow*

Edit:

I could use xclock but this seems like a hack. Ideally I could send the notification anywhere, like my phone, screen, etc.

share|improve this question

migrated from unix.stackexchange.com Mar 2 '11 at 17:57

This question came from our site for users of Linux, FreeBSD and other Un*x-like operating systems..

2  
Although you're at the command line, I think the answer here is actually Mac-specific and not Unix/Linux related. That's because I think you probably want to use Growl and grownlnotify. –  mattdm Mar 2 '11 at 17:30
    
That isn't a build in command, at least on my box. –  Amir Afghani Mar 2 '11 at 17:36
    
growl.info Growl is the program referred to by @mattdm. –  jsbillings Mar 2 '11 at 18:07

10 Answers 10

(svn update . && ant clean build start && say done) || say error

share|improve this answer
    
This is a wonderful example of using shell operators && to chain together several commands and wrap it up with a collective || or statement to raise an error. +1 indeed –  bmike Aug 18 '11 at 3:16
1  
Nice! To be able to do that quickly though, I give up the error vs. success information and added a global alias to my zsh: alias -g sd='; say done'. This means I only have to add sd to any command, and I'll get notified. –  wrtsprt Mar 19 at 16:34

Use Growl.

In the .dmg file, look for the extras, there's a growlnotify binary. Install it, something like in /usr/local/bin. Then you can use this command

growlnotify --sticky --appIcon <icon> --message <message> -t <title>

to show a popup, like that:

growl

share|improve this answer
1  
I use nearly this exact approach but I extend Growl with Prowl so that Growl can push the notification to my iPhone. –  Ian C. Mar 2 '11 at 20:46
2  
Mountain Lion's Notification Center makes Growl unnecessary... see my answer for how to use it for this. –  pelotom Jun 7 '13 at 18:23

In Mac OS 10.8 you can send yourself Notification Center messages (similar to Growl but built in to Mac OS). Check out this page to see how to install a Ruby gem which will allow you to send notifications from the commandline. To simplify the common usecase of just caring about the fact of something in the terminal being done, add an alias to your .bash_profile, e.g.

alias notifyDone='terminal-notifier -title "Terminal" -message "Done with task!"'

Then you can simply do

$ <long-running task> && notifyDone

Once the long-running task finishes you'll get a nice modal popup that persists until you click on it:

Notification Center popup

share|improve this answer

As of Mac OS X Lion 10.7, Terminal has some new status indicators to help with issues like this:

In tabs:

  • Activity: an activity indicator (spinning progress indicator) is displayed when there's been recent output to the terminal. This enables you to see whether it is currently busy or has completed a long process. (Or, of course, you can use it to tell when it has begun producing output after silently performing work for a while.)

  • Unread: an ellipsis "…" is displayed to indicate new, unread text in background tabs. When you select the tab, the indicator is cleared.

  • Alert: a "bell" is displayed to indicate when a BEL has been written to background tabs or background windows. In addition, Terminal displays a red badge on the application icon, indicating the number of "unread" alerts/bells in all terminals. If Terminal itself is in the background, it also bounces its Dock icon when a bell is played.

In minimized window Dock icons:

  • Activity: activity is indicated by displaying the name of the foreground process.

  • Unread: unread text is indicated with an ellipsis.

  • Minimized terminal windows show live content in their Dock icons. This can be used to see whether there's activity, or even to determine what the terminal is doing, if the output you're looking for is identifiable (e.g., a "top" display is fairly easy to recognize even at small sizes). This is especially useful when Dock magnification is turned on or you have room for a large Dock.

In addition, you could display something in the terminal to catch your attention (which would be visible even in minimized windows). For example:

  • Display a large asterisk: banner \*

  • Invert the display: printf '\e[?5h'

  • Paint the display red: tput setab 1; tput clear

  • Sit in a loop, flashing the screen: while true; do printf '\e[?5h'; sleep 1; printf '\e[?5l'; sleep 1; done

There are also escape codes for manipulating windows (move, set size, zoom, minimize, etc.). You could zoom the Terminal window, for example:

printf '\e[9;1t'

See "window manipulation" at http://invisible-island.net/xterm/ctlseqs/ctlseqs.html for details.

Another approach is to use AppleScript to display an alert in a separate window:

osascript -e 'tell app "System Events" to display alert "Build Completed" message "The checkout and build have completed."'
share|improve this answer
    
Excellent use of tput, and escape sequences - you've got everything except for a scrolling message in the title bar! –  bmike Aug 18 '11 at 3:29

You could also use the build in say command for notification, e.g.: say "ant: build: done." See: man say in the terminal.

share|improve this answer

I present in this answer two things:

  • The option of using afplay, which plays sound files, for notification.
  • my tools for reporting exit status along with the notification.

I have this script, ~/bin/donebeep:

#!/bin/bash
if [ "$@" = 0 ]; then
  afplay -v 2 /System/Library/Sounds/Blow.aiff &
else
  afplay -v 2 /System/Library/Sounds/Sosumi.aiff &
fi

This plays a different sound depending on whether the argument is 0. Then I have an alias:

alias donebeep='(savestatus=$?; ~/bin/donebeep $savestatus "$@"; exit $savestatus)'

(That they have the same name is irrelevant and probably a bad idea.)

To use it in your example, svn update . && ant clean build start; donebeep. Note that I am using ; rather than &&, so that it can notify me on failure as well as success.

Before I learned about afplay, I used say to speak messages instead. The role of donebeep was played by this script:

#!/bin/bash
say -v Bruce "Done $(basename "$(pwd)"), $@." &

This script speaks the exit code directly instead of having two different messages. It also mentions the name of the current directory (to help clarify which task is done), and can be given additional text to say by passing parameters to the alias (that's why the alias has "$@" in it). Note the trailing & so that you do not need to wait for the speech to finish before getting a prompt.


The man page for afplay is incomplete; afplay -h lists all options:

Usage:
afplay [option...] audio_file

Options: (may appear before or after arguments)
  {-v | --volume} VOLUME
    set the volume for playback of the file
  {-h | --help}
    print help
  { --leaks}
    run leaks analysis  {-t | --time} TIME
    play for TIME seconds
  {-r | --rate} RATE
    play at playback rate
  {-q | --rQuality} QUALITY
    set the quality used for rate-scaled playback (default is 0 - low quality, 1 - high quality)
  {-d | --debug}
    debug print output
share|improve this answer

I know I'm late to the question but I think there's a little missing piece that may be helpful. I've found that, while it's neat, having your terminal talk with you isn't exactly functional. What's better is something more subtile like this:

http://i.stack.imgur.com/FaZmF.png

As Chris pointed out, Lion has added little notification badges when a BEL is thrown. You can throw it yourself this with the command:

tput bel

So, if you're doing some work in the background and want a notification when it finishes you can try something like:

ping -c 5 www.google.com && tput bel &

This runs the ping command as a background task (the hanging & accomplishes this) and has it throw a simple alert when it finishes. Historically BEL has been used to make that [horrible] hardware beep, however Lion has tastefully replaced that with the "invalid command" sound effect, a notification badge, and the terminal icon bouncing twice in the dock.

share|improve this answer
    
printf '\a' would be equivalent to tput bel. Note that Terminal doesn't bounce the Dock icon if the tab that caused the alert is currently active. –  ؘؘؘؘ Jul 17 '12 at 17:51

My problem with sounds and modal windows is that I cannot tell where they come from. I currently work with a bunch of spaces, and sometimes upwards of 20 terminal windows.

My solution is portable to the unix side, and should work with anything that supports ansi escape sequences. This solution works with Snow Leopard, and will probably work with more ancient versions of terminal.

Single line in .bash_profile

function watch { $* ; echo -n -e "\033[41m" ;  echo $* DONE ;  date ;  echo -n -e "\033[0m" ; }

Breaking that down:

$* expands to the original command I want to watch.
first escape sequence changes background color to red
echo repeats the command (with red background, the word DONE.
Running Date tells you when it finished.
last escape resets the terminal to what it was.

If you don't like red, google ascii escape codes background color. Note that this does not change the whole screen red, but just anything output after the command has finished.

share|improve this answer

I create a simple tool that does exactly this. https://github.com/vikfroberg/brb

Installation

Node.js needs to be installed: http://nodejs.org

$ npm install -g brb

Instructions

$ sleep 3; brb
share|improve this answer
    
This requires node.js to be installed, correct? –  patrix Jun 8 at 14:07
1  
Correct, I'll edit my answer –  Viktor Fröberg Jun 8 at 17:17

Ubuntu ships the following alias in ~/.bashrc:

alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

With this, you can then do things like:

make; alert
sleep 10; alert

Perhaps there's an equivalent to notify-send in Mac OSX? I've seen similar popup Windows in both Mac and Ubuntu.

share|improve this answer
    
You're on the Apple site. To make this an answer, please explain how to get notify-send on Mac OS X. –  Daniel Beck Feb 17 '12 at 8:01
2  
I agree that this is kind of inappropriate, but I actually found this helpful. I came to this question from Google, and my original question was not Mac-specific. Like the original poster, I want a way to not have to monitor my terminal when running command that takes a long time; I just happen to be using Ubuntu :/ –  allyourcode Apr 23 '12 at 22:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.