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/kxbevd.cf <<EOF soundDirectory="/usr/share/sounds/" soundCmd="aplay -q" Bell() "question.wav" EOF
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 fi EOF
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:
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: 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.