html
The Message of the Day (/etc/motd) file in Linux systems displays static content upon user login. By default, it doesn't support dynamic shell command execution like:
$(uptime)
or
uptime
These attempts fail because /etc/motd is processed as a plain text file by the login system, not as a shell script.
Method 1: Using update-motd (Debian/Ubuntu)
Modern Debian-based systems provide a better solution:
# Create executable script in /etc/update-motd.d/
sudo nano /etc/update-motd.d/10-system-stats
#!/bin/sh
echo "System uptime: $(uptime)"
echo "Load average: $(cat /proc/loadavg)"
# Make executable
sudo chmod +x /etc/update-motd.d/10-system-stats
Method 2: PAM motd Module
Configure PAM to execute scripts:
# Edit /etc/pam.d/sshd
session optional pam_motd.so motd=/run/motd.dynamic
# Create dynamic generation script
sudo nano /usr/local/bin/generate-dynamic-motd
#!/bin/bash
echo "=== System Information ==="
echo "Hostname: $(hostname)"
echo "Uptime: $(uptime -p)"
echo "Disk Usage: $(df -h / | awk 'NR==2{print $5}')" > /run/motd.dynamic
Method 3: Cron Job with Static File
# Create script
sudo nano /etc/cron.hourly/update-motd
#!/bin/bash
{
echo "Last updated: $(date)"
echo "Users logged in: $(who | wc -l)"
echo "Memory usage: $(free -h | awk '/Mem/{print $3"/"$2}')"
} > /etc/motd
When implementing dynamic MOTD:
- Restrict script permissions (root ownership, 755)
- Validate all command outputs
- Use absolute paths in cron jobs
- Consider resource usage for frequent updates
Verify changes without logout:
# For SSH:
ssh localhost
# For console:
cat /run/motd.dynamic
Many sysadmins wonder whether they can embed shell commands directly in /etc/motd to create dynamic login banners. The short answer is no - the Message of the Day file is a static text file that doesn't interpret shell commands or variables.
When you try commands like:
$(uptime)
or
uptime
These appear literally in the motd because:
- The file is read directly by login processes
- No shell interpretation occurs during display
- Security restrictions prevent command execution
Here are three working approaches to achieve dynamic motd content:
1. Update motd via Cron
Create a script to regenerate motd periodically:
#!/bin/bash
echo "System Uptime: $(uptime)" > /etc/motd
echo "Last Login: $(last -n 1)" >> /etc/motd
Then add to crontab:
*/5 * * * * root /usr/local/bin/update_motd.sh
2. Use pam_exec with update-motd
On Debian/Ubuntu systems:
# Create dynamic files in /etc/update-motd.d/
cat << EOF > /etc/update-motd.d/10-system-stats
#!/bin/sh
echo "Uptime: $(uptime)"
EOF
chmod +x /etc/update-motd.d/10-system-stats
3. Custom SSH Banner
For SSH-specific messages:
# In /etc/ssh/sshd_config
Banner /etc/ssh/dynamic_banner.sh
Then create an executable script:
#!/bin/bash
echo "=== SSH Server ==="
echo "Current time: $(date)"
echo "Connected from: $SSH_CLIENT"
When implementing dynamic content:
- Ensure scripts are owned by root
- Set proper permissions (755 for dirs, 644 for files)
- Validate all command outputs
- Consider using static information where possible
For most systems, the update-motd method provides:
- Better performance than cron-based solutions
- More maintainable script organization
- Built-in framework on Debian/Ubuntu