dpc's blog

Unix Geek ideas on the go.

Teach Your Shell How to Grab Your Attention

| Comments

In my daily work it’s often a case when I have long-running process that I have to wait for to complete and I don’t want to stare at the shell all the time.

Some terminal emulators do have features like “Monitor for Silence/Activity”, but gnome-terminal does not. That’s why I decided to build something more shell-based and generic.

To do what I want I’ve created two commands. First is tick that I store under $HOME/bin/tick:

1
2
3
4
5
#!/bin/sh

if which mplayer 1>/dev/null ; then
  mplayer -quiet -nolirc "$HOME/usr/sounds/tick.ogg" 1>/dev/null 2>/dev/null &
fi

I use it during daily work, and in some of my scripts to play simple, short “tick”.

Second is notify, which is a bit more extensive notification command. The content of $HOME/bin/notify is:

1
2
3
4
5
6
7
8
9
#!/bin/sh

if which mplayer 1>/dev/null; then
  mplayer -quiet -nolirc "$HOME/usr/sounds/alarm.ogg" 1>/dev/null 2>/dev/null &
fi

if which notify-send 1>/dev/null ; then
  notify-send -t 3000 --hint=int:transient:1 -- "$1" "$2"
fi

Not only it plays longer and louder alarm sound, but additionally it uses notify-send to display notification on your desktop so you know exactly what happened.

Integrate tick and notify into ZSH

In a depth of my complex ZSH configuration I do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function preexec {
  export ZSH_CMD_TICK_TS=`date '+%s'`
  export ZSH_CMD_TICK_CMD="$1"
}

function precmd {
  line-tick
}

export ZSH_CMD_TICK_TS=`date '+%s'`

function line-tick() {
  TS=`date '+%s'`

  if [ $(($ZSH_CMD_TICK_TS + 60)) -lt $TS ]; then
      notify "Cmd finished: $ZSH_CMD_TICK_CMD"
  elif [ $(($ZSH_CMD_TICK_TS + 10)) -lt $TS ]; then
      tick
  fi
  export ZSH_CMD_TICK_TS=$TS
}

So what does it do? First, before execution of every command preexec will record current timestamp and command that is about to be executed. Then, after command has finished, but before the new prompt is displayed precmd will call line-tick to check what should be done. line-tick will compare the current timestamp with the one recorded by preexec. If the time spent on execution of the command is longer than 60 seconds, notify command will be triggered to tell us what command has finished and play alarm sound. If the command execution time was smaller, but still longer than 10 seconds tick will be used instead.

Comments