I was asked yesterday about an alias in Debian systems. Here it is:
Let’s break this down.
First off, alert
will expand to run notify-send
.
An obvious place to start, then, is man notify-send
.
The manual states that the required argument is the summary, and that the
-i
option names an icon to display.
So, the first mystery string names an icon:
And the second is the summary:
(note that the original argument to sed is delimited by '\''
, because
the command is already inside a quoted string for the alias)
Let’s focus on the icon.
In Bash, &&
and ||
work similarly to C’s boolean operators.
&&
means “execute the first command, and, if it completes successfully, execute the second command”.
||
means “execute the first command, or, if it fails, execute the second command”.
Whether a program completes successfully or not depends on its exit status,
aka the return value from int main()
.
If main
returns 0
, then the command is successful.
Otherwise, it failed.
(This is an inversion of C where 0
means false
and nonzero means true
.
This is so programs can return different status codes for different errors.)
The commands true
and false
can be used to demo these operators.
When these operators are chained, &&
has higher precedence than ||
.
Let’s see how those echo
commands execute:
So, that just leaves this chunk of punctuation: [ $? = 0 ]
The first unobvious thing to know is that the square bracket is actually an
alternative name for the test
command.
You can read about it using man test
.
The test
command is given the arguments $? = 0
.
The = 0
part should be self-explanatory: it’s comparing something to zero.
Specifically, it’s comparing $?
to zero.
Anything that starts with a $
is a shell variable.
The $?
variable contains the exit status of the last command.
Remember true
and false
?
Other magical punctuation variables can be found in man bash
in the section
“Special Parameters” (use /
to search).
So, the expression checks the exit status, then prints either “terminal” or “error”.
This expression is wrapped in $()
.
This is called a “Command Substitution” (again, search for this in man bash
).
Basically, the command in parentheses is executed, and its stdout
is spliced
into the command line.
This particular command prints either “terminal” or “error”; one of those
strings will then become the value for notify-send
’s -i
option.
Now, what about the “summary” argument?
The |
is a pipeline (again, search in man bash
. Also, <esc>-u
will clear
the search highlighting).
The first command is executed, its stdout
is sent to the second command’s
stdin
, that command’s stdout
is sent to the third command’s stdin
, etc.
The commands in this case are history
, tail
, and sed
.
The history
command displays all of the commands you have entered so far (up
to a configurable limit).
The tail
command prints the last few lines of its input.
The -n1
option means to print the last 1
lines (i.e. the last line).
This line is then sent to sed
, the stream editor.
sed
is given a string of editing instructions on its command line.
It applies these instructions to its stdin
and prints the results on stdout
.
The most-used editing instruction is s
, which is short for “substitute”.
It performs a regular expression substitution on each line of input.
Like many languages, sed
’s editing instructions are delimited by ;
.
This command actually contains two s
instructions.
The syntax for s
is s/pattern/replacement/
.
You can work out for yourself what the patterns are doing, but notice that
the replacement sections are empty, effectively deleting whatever text is
matched by the patterns. (hints: man 7 regex
, look at the output of history
compared to the message in notify-send
)
Further research on Bash scripting: