Awesome MOTDs with Ubuntu

As computer geeks, we all get a warm and fuzzy feeling when looking at ASCII art and well structured information and it seems that the Ubuntu Community loves us so much.
In Ubuntu 10.04 it’s been introduced a great and well structured way to build awesome MOTDs. A MOTD or Message Of The Day, is a brief message presented to the user which logs in a console (nowadays mostly via ssh) meant to make the user aware of useful information.
Historically the MOTD was meant for a sysadmin to share information with system users. This meant that che information presented by the MOTD was mostly static and edited by hand by a system administrator. Times have changed, cloud computing and configuration management tools like Chef and Puppet, brought the need for a more dynamic MOTD. Ubuntu 10.04 managed to standardize many “hacky” solutions in one structured and simple solution via pam_motd.
MOTD fragment scripts are stored inside /etc/update-motd.d/, executed at each login, the result of the execution outputted to /var/run/motd which is symlinked by /etc/motd.
For example this is what we have now on production servers:
[email protected]:~$ ls /etc/update-motd.d/
0-header 1-info 2-fortune 3-footer
Each file is prefixed by an integer which will determine the order of execution.
Let’s examine each file (we’ll skip 0-header and 3-footer since they’re static):
[email protected]:~$ cat /etc/update-motd.d/1-info
#!/bin/sh
UPTIME_DAYS=$(expr `cat /proc/uptime | cut -d '.' -f1` % 31556926 / 86400)
UPTIME_HOURS=$(expr `cat /proc/uptime | cut -d '.' -f1` % 31556926 % 86400 / 3600)
UPTIME_MINUTES=$(expr `cat /proc/uptime | cut -d '.' -f1` % 31556926 % 86400 % 3600 / 60)
cat << EOF
% %
%+++++++++++++++++++++++++++++++ SERVER INFO ++++++++++++++++++++++++++++++++%
% %
Name: nebulab.com
Uptime: $UPTIME_DAYS days, $UPTIME_HOURS hours, $UPTIME_MINUTES minutes
CPU: `cat /proc/cpuinfo | grep 'model name' | head -1 | cut -d':' -f2`
Memory: `free -m | head -n 2 | tail -n 1 | awk {'print $2'}`M
Swap: `free -m | tail -n 1 | awk {'print $2'}`M
Disk: `df -h / | awk '{ a = $2 } END { print a }'`
Distro: `lsb_release -s -d` with `uname -r`
CPU Load: `cat /proc/loadavg | awk '{print $1 ", " $2 ", " $3}'`
Free Memory: `free -m | head -n 2 | tail -n 1 | awk {'print $4'}`M
Free Swap: `free -m | tail -n 1 | awk {'print $4'}`M
Free Disk: `df -h / | awk '{ a = $2 } END { print a }'`
Public Address: `ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'`
Cloud Address: `ifconfig eth1 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'`
EOF
[email protected]:~$ cat /etc/update-motd.d/2-fortune
#!/bin/sh
cat << EOF
% %
%+++++++++++++++++++++++++++ WISE WORD OF THE DAY +++++++++++++++++++++++++++%
% %
`/usr/games/fortune -as | sed "s/^/ /"`
% %
EOF
The final result is:
|
. -O-
. | * . -0-
* o . ' * . o
. . | *
* * -O- .
. * | ,
. o
.---.
= _/__~0_\_ . * o '
= = (_________) .
. *
* - ) - *
. .
* . * .--.
/ / ` +
. + | | o
' \ \__,
o * + '--' * *
+ /\
+ .' '. * .
* /======\ +
;:. _ ;
. |:. (_) | . +
|:. _ |
+ |:. (_) | * +
;:. ;
.' \:. / `. + '
/ .-'':._.'`-. \
* |/ /||\ \| +
_..--"""````"""--.._
_.-'`` ``'-._
-'jgs '-
:::: ::: :::::::::: ::::::::: ::: ::: ::: ::: :::::::::
:+:+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+:
:+:+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+
+#+ +:+ +#+ +#++:++# +#++:++#+ +#+ +:+ +#+ +#++:++#++: +#++:++#+
+#+ +#+#+# +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+
#+# #+#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+#
### #### ########## ######### ######## ########## ### ### #########
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% %
% WELCOME! %
% %
% This is a Nebulab (http://nebulab.com) server. %
% %
% %
%+++++++++++++++++++++++++++++++ SERVER INFO ++++++++++++++++++++++++++++++++%
% %
Name: nebulab.com
Uptime: x days, y hours, z minutes
CPU: Quad-Core AMD Opteron(tm) Processor 2374 HE
Memory: xM
Swap: yM
Disk: zG
Distro: Ubuntu 10.04.3 LTS
CPU Load: x, y, z
Free Memory: xM
Free Swap: yM
Free Disk: zG
Public Address: 31.222.165.143
Cloud Address: x.y.z.k
% %
%+++++++++++++++++++++++++++ WISE WORD OF THE DAY +++++++++++++++++++++++++++%
% %
<Addi> Alter.net seems to have replaced one of its router with a zucchini.
% %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
Which is well, pretty darn sweet!
One piece of advice: you can escape complex ascii characters with:
cat << 'EOF'
:::: ::: :::::::::: ::::::::: ::: ::: ::: ::: :::::::::
:+:+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+:
:+:+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+
+#+ +:+ +#+ +#++:++# +#++:++#+ +#+ +:+ +#+ +#++:++#++: +#++:++#+
+#+ +#+#+# +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+
#+# #+#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+#
### #### ########## ######### ######## ########## ### ### #########
EOF
Delimiting EOF with single quotes.
Have fun and tell us what you use MOTD for.
Useful resources
- Wikipedia Motd article
- Ubuntu motd Manpage
- Ubuntu pam_motd Manpage
- JGS’s ASCII Art from which we took the spaceship! <3 Thanks jgs <3
- FIGlet an ascii art banner generator
- Fortune Manpage