Awesome MOTDs with Ubuntu

Matteo Latini

3 Jul 2012 Development

Matteo Latini

4 mins
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:

matteo@nebulab:~$ 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):

matteo@nebulab:~$ 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
matteo@nebulab:~$ 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

You may also like

Let’s redefine
eCommerce together.