Ubuntu 16.04 Dynamic MOTD

If you have ever used Ubuntu Server prior to its newest release of 16.04, then you should be familiar with the dynamic MOTD. Previously, 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, Ubuntu Server 16.04 does not include the dynamic MOTD by default in this release. First you will need to install some prerequisites and build the directory structure. To do so, run the following commands in terminal.

# install lsb-release 
apt-get install lsb-release
# install figlet to enable ASCII art
apt-get install figlet
# install update-motd software
apt-get install update-motd
# delete default directory
rm -r /etc/update-motd.d/
# create new directory
mkdir /etc/update-motd.d/
# create dynamic files
touch /etc/update-motd.d/00-header ; touch /etc/update-motd.d/10-sysinfo ; touch /etc/update-motd.d/90-footer
# make files executable
chmod +x /etc/update-motd.d/*
# remove MOTD file
rm /etc/motd.dynamic

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:/ { printf("%3.1f%%", $3/$2*100) }'`
swap_usage=`free -m | awk '/Swap:/ { printf("%3.1f%%", $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
/usr/lib/update-notifier/update-motd-reboot-required
/usr/lib/update-notifier/apt-check --human-readable
echo
#!/bin/sh
#
#    99-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.motd-ubuntu16

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

29 thoughts on “Ubuntu 16.04 Dynamic MOTD

  1. Didn’t work for me on Ubuntu 16.04 server until I did this:
    Edit /etc/ssh/sshd_config
    UsePAM yes
    PrintMotd no

    Then restart SSH…
    sudo service ssh restart

  2. very nice guide, worked flawless for me on a 16.04-server, thank you very much for it. ๐Ÿ™‚

    but one thing stays, and is shown TWO times below the last line (local user…) and it is this bunch of text:

    “The programs included with the Ubuntu system are free software;
    the exact distribution terms for each program are described in the
    individual files in /usr/share/doc/*/copyright.

    Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
    applicable law.”

    i just dont know where it comes from. the only clue is that iยดm using a new user only for ssh-access, maybe theres something somewhere, but i just dont know where to look at… any hints?

        1. Take a look at /etc/update-motd folder and ensure there are no other files in there besides those listed in the article.

          1. i checked the files; its a fresh install following your instructions above. the dynamic-file contains only what your example will show. and more should not be printed at login. i found lots of similar postings, maybe pointing to a bug. dunno. basically its working correct the way you are describing it above. o.O

    1. A reboot is not required. Please ensure you have run every command in the first code block.

      1. Everything but the comments haha

        I do get failure saying there is no motd.dynamic to remove. However that shouldn’t be an issue. This isn’t a total loss on my current server, I just wanted to have it working so I can add the motd to future server when we get them off of 14.

  3. I’ve set this up on an LXD container and get the following error:

    :~# run-parts /etc/update-motd.d/

    /etc/update-motd.d//00-header: 24: /etc/update-motd.d//00-header: Syntax error: “&” unexpected
    run-parts: /etc/update-motd.d//00-header exited with return code 2
    System information as of: Fri Sep 16 11:32:29 UTC 2016

    System Load: 0.04 IP Address: 10.1.1.130
    Memory Usage: 3.3% System Uptime: 2 min
    Usage On /: 1% Swap Usage: 0.0%
    Local Users: 1 Processes: 23

    10 packages can be updated.
    0 updates are security updates.

    /etc/update-motd.d//90-footer: 24: /etc/update-motd.d//90-footer: Syntax error: “&” unexpected
    run-parts: /etc/update-motd.d//90-footer exited with return code 2

  4. Great write-up! I have a few suggestions. Since these scripts run upon each ssh connection it is important they run fast. “route” command by default performs DNS lookup/address resolution. This may be, and often is, slow and my be measured in full seconds. To avoid the annoying lag “-n” switch can be used. When doing that “grep” should be tweaked as well to search for “0.0.0.0” instead of default. So the final snippet should look like “route -n | grep ‘^0.0.0.0’ -m 1” where “-m 1” tells grep that there is no need to continue after the first matching line is found.

    Also both “route” and “ifconfig” are in /sbin directory which means that some environments (e.g. when executed by cron) which don’t have “/sbin” included in $PATH will not work. To make sure the scripts work they need to reference “/sbin/route” and “/sbin/ifconfig”.

  5. the free -m command displays differently on Ubuntu 16.04 and up than previous versions, which is why it always displays 0.0% memory and swap now.

    So on line 23 of 10-sysinfo it should be this I guess?:
    memory_usage=`free -m | awk ‘/Mem:/ { printf(“%3.1f%%”, $3/$2*100) }’`

      1. I am running a fresh install of 16.04.1 and everything is working as expected. Note, I have updated the sysinfo file to report the correct memory usage.

          1. I had been meaning to update the article anyhow, your first comment this morning just reminded me to do so. Thanks

Leave a 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.