Modify the "alert" alias in ~/.bashrc
System: Lubuntu 14.04 LTS
I want to know if it's possible to modify the alert
alias provided in ~/.bashrc
in a particular way. This is the original alert
:
# Add an "alert" alias for long running commands. Use like so:
# sleep 10; alert
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$//'\'')"'
Use of default alias “alert” explains what it does.
And here is an example of the default notification on my system (using xfce4-notify
) when I run ls; alert
which, of course, completes successfully:
If I run a nonsensical command, asdfgh; alert
, I see this:
The terminal
icon has been replaced with the error
icon because of
-i "$([ $? = 0 ] && echo terminal || echo error)"
As of now, the notification has just two items:
- the icon which is terminal
or error
depending on the success of the "previous" command
- the command itself (ls
in the first case and asdfgh
in the second)
I can modify the existing alias to include a line of text above the command like this:
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "Task finished" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
Then, if I run ls; alert
and asdfgh; alert
I get the notifications shown below.
My question is this: Both notifications show "Task finished" but can the same logic that is used to decide whether the terminal
icon or the error
icon is shown be applied again to determine which text string is shown above the command? So, if the terminal
icon displays, the text would be "Task finished" but if the error
icon displays, the text could something like "Something went wrong!"
Tl;dr
Use this:
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && (echo terminal; exit 0) || (echo error; exit 1))" "$([ $? = 0 ] && echo Task finished || echo Something went wrong!)" "$(history | sed -n "\$s/^\s*[0-9]\+\s*\(.*\)[;&|]\s*alert\$/\1/p")"'
Simply evaluating $?
again won't work, because by the time $?
would be evaluated the second time it would contain the first command subsitution's ($([ $? = 0 ] && echo terminal || echo error)
's) exit status (always 0
since the two echo
s would always succed). A trick to go around this would be making the first command substitution exit with an equivalent exit status again:
$([ $? = 0 ] && (echo terminal; exit 0) || (echo error; exit 1))
This way $?
could be evaluated a second time in order to decide which string to print:
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && (echo terminal; exit 0) || (echo error; exit 1))" "$([ $? = 0 ] && echo Task finished || echo Something went wrong!)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]+\s*//;s/[;&|]\s*alert$//'\'')"'
On another note your history|tail -n1|sed -e '\''s/^\s*[0-9]+\s*//;s/[;&|]\s*alert$//'\''
is a bit over-convoluted. This would be way more readable:
history | sed -n "\$s/^\s*[0-9]\+\s*\(.*\)[;&|]\s*alert\$/\1/p"
So, final command:
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && (echo terminal; exit 0) || (echo error; exit 1))" "$([ $? = 0 ] && echo Task finished || echo Something went wrong!)" "$(history | sed -n "\$s/^\s*[0-9]\+\s*\(.*\)[;&|]\s*alert\$/\1/p")"'
You can test by running (exit 0); alert
and (exit 1); alert
.