X Gnome System Beep With Audio File

Using Ubuntu Hardy on a Sony Vaio laptop I had a need for a long-running shell script to ring the bell when it required my attention. This is usually a trivial case of echo-ing an escape-code (0x08) in a gnome-terminal:

echo -e "\a"

However I realised after running the script a few times that the bell wasn't ringing. I tried it on another (desktop) system and it worked. I tried it on a proper tty console (Ctrl+Alt+F1) but it still didn't work. It was then it dawned on me - the laptop doesn't have an internal PC speaker.

I set about looking for an alternative. What was needed was either a way to have Gnome redirect System Beep to its sound event system, or a way to intercept the regular ASCII BELL escape code. I found and tried softbeep but that wasn't any good. Then I found xkbevd (X keyboard event daemon). It is already installed as part of the x11-xkb-utils package.

It needs a per-user configuration file:

mkdir ~/.xkb
# create config file using a HERE document
cat > ~/.xkb/ <<EOF
soundCmd="aplay -q"

Bell() "question.wav"

The daemon needs to be running in the background. If this is for a permanent solution then add it to ~/.profile:

echo <<EOF >> ~/.profile
if [ -n "$DISPLAY" ]; then
  xkbevd -bg

When the user X session starts the daemon and configuration will be active. The command won't run if the log-in is not an X session (a console or remote ssh/telnet session).

To start the daemon manually simply do:

xkbevd -bg

The only limitation is that it doesn't work outside of X, so the tty consoles are still silent.

I discovered later (should have realised when I first wrote this) that when switching to a regular non-X tty having xkbevd in the user shell profile would cause a problem. The console shows reports:

Error: Cannot open display "(null)"

and /var/log/messages will show something like:

kernel: [ 2477.743525] xkbevd[16384]: segfault at a20 rip 7ffb126dc898 rsp 7fff1ad8af50 error 4

To deal with that I've updated this page to only load xkbevd if an X session is running.