I would like to have a dynamic motd, but I can't figure out how to do it.

I tried what I found, adding /etc/update-motd.d/00-header, 10-sysinfo, 90-footer, and symlinking to /etc/motd /var/run/motd.dynamic, /run/motd.dynamic, /run/motd or /var/run/motd.

I've got these lines in /etc/pam.d/sshd:

# Print the message of the day upon successful login.
# This includes a dynamically generated part from /run/motd.dynamic
# and a static (admin-editable) part from /etc/motd.
session    optional     pam_motd.so  motd=/run/motd.dynamic
session    optional     pam_motd.so noupdate

I'm also confused with systemd.

Is there a way to do this? Could someone provide a example with a simple fortune?

  • 1
    wouldn't pam_motd.so noupdate be the problem there?
    – Jakuje
    Commented Nov 30, 2015 at 22:41

3 Answers 3


This has changed over the years:

First there was /etc/motd (static).

Then Ubuntu came up with their own package update-motd based on a script called from cron.

Finally, PAM copied Ubuntu's idea of /etc/update-motd.d/, and therefore Debian and others also have that behaviour.

There is an explanation here


So this is how things are currently: PAM will just read /var/run/motd.dynamic and /etc/motd if it exists (paste from post)

  • /etc/motd – The classic, static file. Does not exist anymore in Ubuntu 16.04 LTS, not even as a symbolic link to /var/run/motd. If it is created, however its contents will be printed too.
  • /var/run/motd – This was used by Ubuntu’s first implementation. It is not used anymore. It is just ignored by PAM.
  • /var/run/motd.dynamic – This is what is shown on login currently. It is updated by /etc/init.d/motd at every boot. It is also updated by PAM by running the scripts in /etc/update-motd.d/, if they exist.
  • /etc/motd.tail – The Ubuntu package used to populate /etc/update-motd.d. One of them would cat the contents of this file so it was easy to add static content. That script does not exist in the package anymore, so the file does not have the intended effect.

The example from the post

mkdir /etc/update-motd.d
rm -f /etc/motd                  # in Debian still exists
cat > /etc/update-motd.d/10logo <<EOF
cat /etc/issue

cat > /etc/update-motd.d/20updates <<'EOF'
echo "uptime is $( uptime )"
echo "date   is $( date   )"

chmod a+x /etc/update-motd.d/*

I am able to test simple dynamic-motd with fortune example on my Debian Jessie 8.2 host as below and found the issue to be related to a buggy behavior.

mkdir /etc/update-motd.d
cd /etc/update-motd.d

Created two test files as below and made them executable

root@debian:/# cd /etc/update-motd.d/
root@debian:/etc/update-motd.d# ls -l 
total 8
-rwxr-xr-x 1 root root 58 Dec  1 23:21 00-header
-rwxr-xr-x 1 root root 41 Dec  1 22:52 90-fortune
root@debian:/etc/update-motd.d# cat 00-header 
echo 'Welcome !! This is a header'
root@debian:/etc/update-motd.d# cat 90-fortune 

However at this time, there was no change in motd. So i strace'd sshd process.From that trace (interesting parts shown below), you can see that newly created motd.new file is renamed to /var/run/motd. However it's later trying to read from /run/motd.dynamic - which was never created

20318 rename("/var/run/motd.new", "/var/run/motd") = 0
20318 open("/run/motd.dynamic", O_RDONLY) = -1 ENOENT (No such file or directory)
20318 open("/etc/motd", O_RDONLY)       = 8

The issue seem to be related to inconsistencies with pam_motd module. See bug report https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=743286;msg=2

Simply changing motd file location from /run/motd.dynamic to /run/motd in /etc/pam.d/sshd - makes it work for me

root@debian:/etc/pam.d# grep pam_motd sshd
#session    optional     pam_motd.so motd=/run/motd.dynamic
session    optional     pam_motd.so motd=/run/motd
session    optional     pam_motd.so noupdate

Here is the sample MOTD seen during ssh login ...

Welcome !! This is a header

* Culus fears perl - the language with optional errors

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
Last login: Tue Dec  1 23:49:57 2015 from x.x.x.x
  • Thank you, it helped! I had to add the .new at the end in /etc/pam.d/sshd: session optional pam_motd.so motd=/run/motd.new and link sudo ln ds /run/motd /etc/motd. And I forgot to export LANG="eo" in order to see the fortune.
    – batisteo
    Commented Dec 2, 2015 at 18:21
  • This solution also works for debian 7.
    – azmeuk
    Commented Sep 5, 2017 at 14:29
  • 1
    This basic solution also works for Debian Stretch 9, with a small tweak - the file to read is now /run/etc/motd.dynamic.new
    – cam8001
    Commented Feb 20, 2018 at 8:36

You may also try these files for script execution.

What is /etc/profile used for? These files are used to set environmental items for a users shell. Items such as umask, and variables such as PS1 or PATH.

What is ~/.bashrc used for? This file is meant for setting command aliases and functions used by bash shell users.

When are these files used? The difference is simple, the /etc/profile is executed only for interactive shells and the ~/.bashrc is executed for both interactive and non-interactive shells. In fact in Ubuntu the /etc/profile calls the ~/.bashrc directly.

(Source: https://bencane.com/2013/09/16/understanding-a-little-more-about-etcprofile-and-etcbashrc/ )

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .