[PATCH] Add desktop notification of completed commands

Bug #315932 reported by Luca Barbieri
126
This bug affects 25 people
Affects Status Importance Assigned to Milestone
bash (Ubuntu)
Triaged
Wishlist
Unassigned

Bug Description

Binary package hint: bash

The code uploaded here, released to the public domain, modifies the default bashrc to notify the user when a command completes and the terminal is not in focus.

It works by adding a custom PROMPT_COMMAND that uses a new C program called "xactive" to determine whether the terminal window is active and if not uses notify-send to popup a notification.

The code to add to /etc/bash.bashrc and xactive.c are attached.

To test, type "sleep 5", press Enter, Alt-Tab, and wait for the notification.

xactive should probably be put in a separate package since it depends on X11 (which should be depended on by ubuntu-desktop).

Add the following to /etc/bash.bashrc:

function prompt_command
{
 if test -n "$DISPLAY" && test -n "$WINDOWID" && test -n "$DBUS_SESSION_BUS_ADDRESS" && test -x /usr/bin/xactive && test -x /usr/bin/notify-send && test -x /usr/bin/tail && test -x /bin/sed && ! /usr/bin/xactive "$WINDOWID"; then
  local body="$(HISTTIMEFORMAT= history|/usr/bin/tail -n 1|/bin/sed -re 's/^ *[0-9]+ *//')"
  local timeout=3000
  if test "$UID" != 0 || test "$USERNAME" == root; then
   /usr/bin/notify-send -u low -t "$timeout" -i terminal -c terminal "Terminal task finished" "$body"
  elif test -x /usr/bin/sudo; then
   /usr/bin/sudo -u "$USERNAME" /usr/bin/notify-send -u low -t "$timeout" -i terminal -c terminal "Administrative terminal task finished" "$body"
  fi
 fi
}

PROMPT_COMMAND=prompt_command

Tags: alert
Revision history for this message
Luca Barbieri (luca-barbieri) wrote :
Revision history for this message
Matthias Klose (doko) wrote :

sounds like the perfect recipy to make your desktop more noisy ... not sure if I just want to close this as won't fix.

Changed in bash (Ubuntu):
importance: Undecided → Wishlist
status: New → Triaged
Revision history for this message
Dustin Kirkland  (kirkland) wrote :

See:
http://blog.dustinkirkland.com/2010/07/dear-command-line-please-ping-me-when.html

Developed independently from this bug...

  alias alert='notify-send -i gnome-terminal "[$?] $(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/;\s*alert$//'\'')"'
  sudo apt-get install libnotify-bin
  sleep 20; alert

The response in the comments from planet.ubuntu.com readers has been very positive. I think it might be a nice addition to Ubuntu's bashrc. It won't make things noisy, as Doko mentioned, since the user has to do "; alert" at the end of their command.

Revision history for this message
Paul Sladen (sladen) wrote :

Dustin Kirkland has just independently reinvented feedback from long-run background commands again; which I came to file as a wishlist and then found this bug report (with patch no-less...). Here's kirkland's solution:

  http://blog.dustinkirkland.com/2010/07/dear-command-line-please-ping-me-when.html

on the commends on that post several other people mention having done equivalent mash ups themselves; which seems to be indicate a use-case.

Remember Ubuntu developed and add 'command-not-found' and the sudo first-run notification, and those distros rapidly followed-suite.

Revision history for this message
Paul Sladen (sladen) wrote :

Stepping back slightly, I think there's a wider issue here. Currently various desktop applications are hooked to use notify-osd, browser, chat programs, power-management.

The logical extension is to argument command-line programs to push information to notify; however I doubt those those small command line tools will really want to link and depend on libnotify instructure; so perhaps there's a case for doing this like 'bash_completion'; refer to a directory and then ship program-specific shell scripts that hook into the infrastructure---where the central infrastructure is doing things like detecting that the shell in question is in the background and not-focused.

We shouldn't be printing numeric exit codes for the applications, but application-specific extensions could decode those into human-readable text (the man code normally documents what is what) or at a minimum "Finished sucessfully"/"Experienced a problem" perhaps.

Somebody explicitly mentioned that this should also work with commands being run across ssh sessions. The top application to start with for me with be 'wget'; probably followed by 'scp'.

The other option is to hook gnome-terminal et al through the ASCII escape code terminal infrastructure (currently used to update the titlebar with "user@machinename").

Revision history for this message
Dustin Kirkland  (kirkland) wrote :

wget, curl, scp, rsync, make, ...

And yes, the return code could be dropped in favor of two different icons being displayed instead, one of a terminal with a big fat green check/tick mark, and the other with a big fat red X.

I'm with you Paul. +1.

Revision history for this message
Luca Barbieri (luca-barbieri) wrote :

Thanks for the support for this wishlist item!

I think automatic notification is better than an "alert" alias, as long as it only happens when you are not using the terminal, as my proposed code does.

The system is not noisy at all (since, again, you don't get notification if the terminal is focused) and can be quite useful in practice, especially to tell you when "make" finished.

Adding a success/failure icon seems useful, and perhaps the latest output line could also be provided, but I'm not sure application-specific code is otherwise really useful (any example?)

And yes, it is probably much better to integrate this mechanism in gnome-terminal and konsole, since that will work fine for remote and chrooted shells and avoids the kludge of spawning a process to determine if the terminal is active or not on every prompt.

On the other hand, the bash solution will work in any terminal that provides the WINDOWID variable with the X window ID of the terminal window or any child of it.

Changed in bash (Ubuntu):
assignee: nobody → Dustin Kirkland (kirkland)
Revision history for this message
Paul Sladen (sladen) wrote :

Been pondering this over the intervening time period; the extend depends on how narrow the focus is kept. It would probably be better to get something working reliably as a proof of concept: eg. bash and gnome-terminal for the moment:

The notification routeing can be:

  a. bash -> callout -> notify
  b. bash -> ... -> terminal -> notify

(a) only works locally, it doesn't transit SSH, but only require only a bash script entry adding.
(b) works locally *and* transits SSH (using in-band escape-sequence signalling), but not a background GNU Screen window (I believe). It requires a bash script addition and a *-terminal patch.

For the actual argumentation of the interactive environment (required for both), there appear to be:

  $PROMPT_COMMAND=/path/to/exec

or:

  $PS1=`/path/to/exec`

or:

  patching individual applications (make, wget, curl, rsync).

For the first, I've tried setting PROMPT_COMMAND='/usr/bin/env | less -S' but there doesn't appear to be any useful data passed in the environment.

As for the actual notification data, the success/fail icon idea sounds an excellent way to pass the status without wasting confusing text on it. I'd probably want to see the name of the command ("make all", "rsync foobar/ somewhere:/...", and the machine name (terminal title) if it is remote. The output only needs to be verbose enough to identify uniquely the terminal it came from; so if there are two "make all"s that were running in non-focused windows then there should be a enough to disambiguate them (yes, this needs some intelligence).

Perhaps one approach would be to specify a encoding of a passive pseudo libnotify call encoded in a (new) "ANSI" escape sequence.

Revision history for this message
Marius Kruger (amanica) wrote :

I think this should be automatic i.e. you shouldn't have to remember to add a ;alert , because most of the times you would need this you would only realize it after you ran the command.
This needn't be the default behavior, but could for example be activated by a configuration option in Konsole.

Revision history for this message
Paul Sladen (sladen) wrote :

Marius: things on Ubuntu should "just work". If it's worth doing, it's worth doing automagically!

Doing background notification from command-line processes properly is a hard(tm) problem; to be optimal it will need introspection adding at multiple levels in the stack. But if you're going to that effort it should be there by default for everyone out-of-the-box.

The key to making it useful and transparent is to refine what should be notified (eg. when in background) and what should be contained in that notification (ideally more information than just "finished").

Revision history for this message
Dustin Kirkland  (kirkland) wrote : Re: [Bug 315932] Re: [PATCH] Add desktop notification of completed commands

Okay, so this Thursday (August 12th) is FeatureFreeze for Maverick.

If any of this is going to make Maverick, we need to upload something ASAP.

While I would love to see this all automatic and automagic, I just
don't think it's going to get any better than this right now for
Maverick (given my other work items):

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

I'm happy adding this to Ubuntu's default bash .profile installed.
Users who want to use this feature, will 'sudo apt-get install
libnotify-bin' and then append the "; alert" onto the end of commands
that they want to be alerted about.

Ideally, this "feature" will be useful enough to people that we can
get a full spec about the "best" way to implement this in Maverick+1
in a by-default, automatic, automagic manner.

What do you think?
:-Dustin

Revision history for this message
Luca Barbieri (luca-barbieri) wrote :

How about using my solution then?

It does work automagically, as long as the shell is running locally.

It is essentially an improved version of the alert alias, that runs automatically on each prompt, but only if the terminal is inactive.

It needs a command line way to find out if the terminal is active or not, which is provided by the "xactive" C program I posted here, since I couldn't find a way to do the same easily otherwise.

This only adds the slight hassle of packaging the xactive program too, noting it either needs a dependency on libx11, or to be changed to load it dynamically.

Also, the Ubuntu developer doing this will need to figure whether to put it into the bash package or in a separate package, keeping in mind that xactive and libnotify-bin will need to be installed too for it to do anything at all.

On the other hand, the "alert" alias is in my opinion much less useful, especially because the user needs to realize it exists, and I doubt a lot of people will notice it.

Revision history for this message
Luca Barbieri (luca-barbieri) wrote :
Download full text (4.0 KiB)

BTW, for Maverick+1, I found a new way to do this, that works for both screen sessions, ssh sessions and the perverse case of remote screen sessions displayed multiple times on multiple terminals.

Changes to Desktop Notification specs/notify-daemon/notify-osd:
1. Add a ID field to the notification: this is an optional 128/256-bit integer randomly generated by the client
2. Add a "holding time" field to the notification
3. If the "holding time" is specified, the notification daemon will wait that amount of time before displaying the notification, and then only display it if a "do not show" flag was not set
4. Any notification with the same ID of a notification being currently held is silently dropped, with the holding time period ending at the maximum of the end of the two holding periods. Optionally, the daemon is allowed to also drop those with the same ID of any notification ever seen. It may also choose to not do this to avoid unlimited memory requirements.
5. A new kind of request is added, called an "notification inhibition request", which contains a required ID like those for notification
6. If a "notification inhibition request" is received, and a notification with that ID is being held, set the "do not show" flag on that notification

Changes to the VT100/xterm terminal specification:
1. Add a new escape code, that carries a full notification as specified in the D-BUS Notification specification plus the extension detailed above

Changes to the bash prompt_command
1. Generate a unique notification ID
2. Pass that to notify-send, along with a sensible holding timeout (e.g. half second)
3. Also print the notification escape code, with all the data

Changes to gnome-terminal, konsole, rxvt, xterm:
1. If a notification escape code is received, and the terminal is active, send a "notification inhibition request" with the ID provided via D-BUS to inhibit the notification
2. If a notification escape code is received, and the terminal is not active, send a notification with the ID and data provided via D-BUS to show it (if not inhibited by another active terminal)

Example results:
1. For local (and bound "screen") sessions on inactive terminals, both the shell and terminal sends a notification: one notification is displayed
2. For local (and bound "screen") sessions on active terminals, the shell sends a notification and terminal sends an inhibition: nothing is displayed
3. For detached local "screen" sessions, the shell sends a notification: one notification is displayed
4. For remote sessions on active terminals, the terminal sends an inhibition: nothing is displayed
5. For remote sessions on inactive terminals, the terminal sends a notification: one notification is displayed
6. For remote "screen" sessions attached to from multiple terminals, all inactive, all the terminals send a notification: one notification is displayed
6. For remote "screen" sessions attached to multiple terminals, with one active, all inactive terminals send a notification, and the active one sends an inhibition: nothing is displayed

Hence, the proposed solution works properly in all cases, as long as the terminal has been patched.

The rationale is:
1. If the sess...

Read more...

Revision history for this message
Dustin Kirkland  (kirkland) wrote :

Luca-

I appreciate all of that. I won't be able to do that by Thursday (2
days from now).

I suppose all of this will need to wait until Maverick+1.

Changed in bash (Ubuntu):
assignee: Dustin Kirkland (kirkland) → nobody
Revision history for this message
Dustin Kirkland  (kirkland) wrote :

Unassigning myself.

Revision history for this message
Luca Barbieri (luca-barbieri) wrote :

Dustin, are you referring also to just adding the "prompt_command" function and "xactive.c" program in the initial bug report, or only to the long proposal I just posted? (which clearly is for Maverick+1 at least, and may not even be worth bothering to implement)

It does change the default shell behavior, possibly introducing issues (although it works for me :) ) but I suppose the post-feature-freeze period is intended for eliminating such potential regressions?

A possible way to do it is to package xactive separately, make ubuntu-desktop depend on it, make bash recommend it, and and add the prompt_command script to the bash profiles in the bash package. I'm not very familiar with Ubuntu packaging policy though, so other options may be better.

Revision history for this message
Paul Sladen (sladen) wrote :

kirkland: lets add that minium 'alert' alias to '/etc/bash_profile' for tomorrow... that can then be used as a persuasive demo for engineering something more in-depth if it proves popular.

Something. Is better than nothing.

Revision history for this message
Dustin Kirkland  (kirkland) wrote :

Paul,

I'm fine with that, but let's do that under a new bug report. I fear
that we have hijacked Luca's original report unfairly. It seems that
he's proposing something different from what I'm proposing with the
"alert" alias. I think the alert alias can be added as a one-liner
trivially by tomorrow, as you say, for proof-of-concept and a
low-touch little feature. The full implementation of automatic
notifications suggested by the original bug report deserves a bit more
work for Ubuntu NN.

:-Dustin

Revision history for this message
Dustin Kirkland  (kirkland) wrote :

Okay, split the "alert" portion of this bug to Bug #616028, and just uploaded that bit to Maverick.

Paul Sladen (sladen)
tags: added: alert
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.