Debian Wheezy Dynamic MOTD

Note: If you are looking for a how-to on Debian Jessie, please see Debian Jessie Dynamic MOTD.
If you have ever used Ubuntu Server then you should be familiar with the dynamic MOTD.  This is what is presented to the user in terminal when a log on occurs.
ubuntu-motd
This feature is very nice as it will give you a quick look at useful information. Unfortunately, Debian Server does not include the dynamic MOTD. A few months back I came across a tutorial on how to add the Dynamic MOTD feature to Debian.  This tutorial was originally written and published here by Nick Charlton. So here we go.  First you will need to install some prerequisites and build the directory structure. To do so, run the following commands in terminal. Please note I have taken the liberty of removing the section that includes updates called “Updates (20-updates)” from the original tutorial as I typically enable automatic security updates on my Debian Servers. UPDATE: if you would like to add update notification, I have written another article detailing the steps here.

# install figlet to enable ASCII art
sudo apt-get install figlet
# create directory
mkdir /etc/update-motd.d/
# change to new directory
cd /etc/update-motd.d/
# create dynamic files
touch 00-header && touch 10-sysinfo && touch 90-footer
# make files executable
chmod +x /etc/update-motd.d/*
# remove MOTD file
rm /etc/motd
# symlink dynamic MOTD file
ln -s /var/run/motd /etc/motd

Once the above commands have been run, you can move on to populating the files you created. Below you can copy and paste.

Header (00-header)

#!/bin/sh
#
#    00-header - create the header of the MOTD
#    Copyright (c) 2013 Nick Charlton
#    Copyright (c) 2009-2010 Canonical Ltd.
#
#    Authors: Nick Charlton <hello@nickcharlton.net>
#             Dustin Kirkland <kirkland@canonical.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

[ -r /etc/lsb-release ] && . /etc/lsb-release

if [ -z "$DISTRIB_DESCRIPTION" ] && [ -x /usr/bin/lsb_release ]; then
        # Fall back to using the very slow lsb_release utility
        DISTRIB_DESCRIPTION=$(lsb_release -s -d)
fi

figlet $(hostname)
printf "\n"

printf "Welcome to %s (%s).\n" "$DISTRIB_DESCRIPTION" "$(uname -r)"
printf "\n"

System Information (10-sysinfo)

#!/bin/bash
#
#    10-sysinfo - generate the system information
#    Copyright (c) 2013 Nick Charlton
#
#    Authors: Nick Charlton <hello@nickcharlton.net>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

date=`date`
load=`cat /proc/loadavg | awk '{print $1}'`
root_usage=`df -h / | awk '/\// {print $(NF-1)}'`
memory_usage=`free -m | awk '/Mem:/ { total=$2 } /buffers\/cache/ { used=$3 } END { printf("%3.1f%%", used/total*100)}'`
swap_usage=`free -m | awk '/Swap/ { printf("%3.1f%%", "exit !$2;$3/$2*100") }'`
users=`users | wc -w`
time=`uptime | grep -ohe 'up .*' | sed 's/,/\ hours/g' | awk '{ printf $2" "$3 }'`
processes=`ps aux | wc -l`
ip=`ifconfig $(route | grep default | awk '{ print $8 }') | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}'`

echo "System information as of: $date"
echo
printf "System load:\t%s\tIP Address:\t%s\n" $load $ip
printf "Memory usage:\t%s\tSystem uptime:\t%s\n" $memory_usage "$time"
printf "Usage on /:\t%s\tSwap usage:\t%s\n" $root_usage $swap_usage
printf "Local Users:\t%s\tProcesses:\t%s\n" $users $processes
echo
#!/bin/sh
#
#    90-footer - write the admin's footer to the MOTD
#    Copyright (c) 2013 Nick Charlton
#    Copyright (c) 2009-2010 Canonical Ltd.
#
#    Authors: Nick Charlton <hello@nickcharlton.net>
#             Dustin Kirkland <kirkland@canonical.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with this program; if not, write to the Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

[ -f /etc/motd.tail ] && cat /etc/motd.tail || true

Once these files are populated with the above, you should now be able to logout and then log back in either using putty or on the console and you will be presented with something that looks like below.debian-motd

 

Revised February 10, 2015 – As Bostjan Bele pointed out below in the comments, the ip variable is looking for the address of eth0. In order to support multiple platforms, he has provided updated code that grabs the default IP Address no matter what the adapter name is. Thanks for sharing Bostjan!

Revised February 3, 2015 – As Alessandro has shared below in the comments, the swap variable has been updated to properly handle a no swap situation. Thanks for the fix Alessandro!

Revised January 30, 2015 – As Bostjan Bele pointed out below in the comments, the time variable has been updated to properly reflect “hours”. Thanks for the fix Bostjan!

Revised January 22, 2014 – Note that the memory calculation being used in the original post was inaccurate. The proper changes have been made to System Information (10-sysinfo) section below. For reference the memory_usage variable has changed.

Did you find this article useful? Why not share it with your friends?

15 thoughts on “Debian Wheezy Dynamic MOTD

  1. For the new debian stretch, ifconfig doesn’t show “inet addr” anymore, so the sequences above don’t work. Here’s what got it going for me:

    ip=`ifconfig $(route | grep default | awk '{ print $8 }') | grep 'inet' |head -n1 | awk '{print $2}'`

    1. I think the following version may be faster:

      ip -o -4 addr |grep $(ip route|grep default|awk ‘{print $5}’)|awk -F”\t|/| +” ‘{print $4}’

      but haven’t tried it out on debian 9…

  2. Hi Matthew,

    thx for your work!
    On Debian Wheezy systems i have to install `lsb-release` as well

    apt-get install lsb-release

    to make 00-header work correctly.

  3. Hi. It works OK, thanks for your work. I saw the “presentation” but i dont like the big letters for my hostname. I edited the 00-header, but if i test the ssh connection to my server, it keeps showing me the original scripts that calls figlet with big letters.
    How can i force to update of the edited script so i can see its changes the next time i connect?
    many thanks.
    Sergio.

  4. On my VPS it seems that your way to fetch the external IP doesn’t work (it returns 127.0.0.2). I wrote an alternative option that works:

    ip=`ifconfig | grep “inet addr” | tail -n 1 | awk ‘{print $2}’ | cut -f 2 -d “:”`

    But… at another VPS which is not mine (it’s from someone else), the above code returns “127.0.0.2” – and your way to get the IP returns the correct IP. Is there someone who could write something that works on both VPSses?

    1. I’m getting with your command 127.0.0.1:

      root@BB-Pi-01 ~ $ ifconfig | grep "inet addr" | tail -n 1 | awk '{print $2}' | cut -f 2 -d ":"
      127.0.0.1

  5. Hi!

    We are using this dynamic motd in our company now on all our servers.

    I made another change as I was not ready to change the 10-sysinfo file each time the ethernet interface has different name. We need to see the “default” interface, which is usually pointing to the default gateway. My replacement is:

    ip=`ifconfig $(route | grep default | awk ‘{ print $8 }’) | grep “inet addr” | awk -F: ‘{print $2}’ | awk ‘{print $1}’`

    Now you can port your files to any debian computer (I use it on my four raspberry pi’s where one has wlan and the other three eth0, then in our company, where we bond more ethernet interfaces, etc.).

    Kind Regards
    Bostjan

  6. Hi!

    I’ve used your dynamic MOTD and it’s awesome. I’ve made a simple workaround for the uptime bug (if uptime is less than 1 day you have instead of “days” the number of users. The workaround is just simple; raplacing the comma with “hours” insted *nothing*:

    time=$(uptime | grep -ohe ‘up .*’ | sed ‘s/,/\ hours/g’ | awk ‘{ printf $2″ “$3 }’)

    Kind Regards
    Bostjan

Leave a Reply to Bostjan Bele Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.