Monday, July 26, 2010

Dear Bash, please ping me when you're done running $FOO


UPDATE: The "alert" alias has landed in Maverick's /etc/skel/.bashrc ... thanks for your support!!!

How often do you run a command line tool on your desktop that takes a really long time? Maybe something like make, debuild, rsync, or wget?

You probably kick off the long running job, and then alt-tab over to something more captivating than watching gcc fill your scroll back buffer -- maybe your web browser or news reader.

You occasionally pop back over to your shell to check on your job. Maybe it's still running. But maybe it finished a while ago. Dang.

No need to beat yourself up over wasted cycles. You can tell your shell to ping you when it's done. Just add this alias to your ~/.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$//'\'')"'

Install the notify-send utility, and source your new ~/.bashrc:

sudo apt-get install libnotify-bin
. ~/.bashrc

Now, run a long running job, and append "; alert" to the end of the command, like this:

sleep 20; alert

After running the target command, the alert alias will render a notify-osd pop-up on your desktop, telling you the command you just ran, and its exit code.


Nifty, huh?

:-Dustin

26 comments:

  1. Been using notify-send for some time, but returning the exit code is an excellent idea!
    Thaaaaaaaaaaanks Dustin :)

    ReplyDelete
  2. it would be even nicer if gnome-terminal could do what multi-gnome-terminal could 8 years ago, and color the title of the tab differently as an implicit notification when no output is done in that tab anymore.

    ReplyDelete
  3. Hey, awesome! Now you said!!! =]]

    ReplyDelete
  4. cool!

    I got to the same exact solution (an alias for nitify-send) no more than three weeks ago :)

    ReplyDelete
  5. I implemented something very similar in python a while back:

    http://github.com/jbernard/informme

    Though, I do like the simplicity of a shell alias. Nice work.

    ReplyDelete
  6. This is great, thanks! I simplified "/usr/share/icons/gnome/32x32/apps/gnome-terminal.png" to just "gnome-terminal", and let notify-send figure out the theme and resolution.

    alias alert='notify-send -i gnome-terminal "[$?] $(alert_helper)"'

    ReplyDelete
  7. I don't like to create two aliases for just one command, so I combined them. :)

    alias alert='notify-send -i /usr/share/icons/gnome/32x32/apps/gnome-terminal.png "[$?] $(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/;\s*alert$//'\'')"'

    Thanks for the idea. Now I just start to wonder how to change the theme of the notification. :)

    ReplyDelete
  8. Meh. "; beep" does the job just as well.

    ReplyDelete
  9. Thanks, I've been doing cheezy stuff to do something like this for a while, but never anything worth putting in a .bashrc. Using history is very handy.

    Thanks

    ReplyDelete
  10. I wonder if you could set up your shell to notify automatically for any command that takes longer than 10 seconds or so. Or any command that finishes in a terminal (or screen window) that doesn't have focus.

    ReplyDelete
  11. I just do
    (command && notify-send Yes) || notify-send No

    ReplyDelete
  12. mpiroc,

    Brilliant! Thanks, updated the code above.

    :-Dustin

    ReplyDelete
  13. rhonda-

    Nice! Updated the alias above!

    :-Dustin

    ReplyDelete
  14. Um, did anyone tested it?
    In my case it only started working after deleting newline character \
    Here is the whole line:
    alias alert='notify-send -i gnome-terminal "[$?] $(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/;\s*alert$//'\'')"'

    ReplyDelete
  15. This is so cool, Dustin. Thanks for posting it.

    ReplyDelete
  16. Works in KDE too. Just replace gnome-terminal with konsole :)

    Thanks.

    ReplyDelete
  17. Could we propose this for the default bashrc on Ubuntu Desktop? Seems useful enough to me for that.

    ReplyDelete
  18. Hey Ted, sure, add your two cents to:
    * https://bugs.launchpad.net/bugs/315932
    and mark it as affecting you.

    :-Dustin

    ReplyDelete
  19. Great stuff Dustin!

    I added some code to remove the trailing "alert" on the notify:

    alias alert='JOB=$(history|tail -n1|sed -e "s/^\s*[0-9]\+\s*//" -e "s/;\s*alert$//"); notify-send -i gnome-terminal "Finished Terminal Job" "[$?] ${JOB%alert*}"'

    ReplyDelete
  20. This is very nice. My only regret is that it doesn’t work with scripts...
    In any case, a nifty little idea =)

    ReplyDelete
  21. Hmm, neat idea. I used to just do this:

    # long command ; espeak 'Long command is done, now'

    But this is a bit more universal, especially for people w/o sound.

    ReplyDelete
  22. be nice if this somehow becomes part of the terminal... save people the need to have to modify any bashrc

    ReplyDelete
  23. now that is just sexy.

    ReplyDelete
  24. This is a weird coincidence. I just made a shell script thing that does the same. But for Mac OS X :P

    ReplyDelete
  25. Mark Szymanski - care to share that script for us Mac folk? It doesn't appear that MacPorts or Fink has notify-send. I found gcin, but not sure it has the same capabilities. Perhaps Growl has a command line equivalent?

    ReplyDelete

Please do not use blog comments for support requests! Blog comments do not scale well to this effect.

Instead, please use Launchpad for Bugs and StackExchange for Questions.
* bugs.launchpad.net
* stackexchange.com

Thanks,
:-Dustin