Dynamic Message of the Day - Raspberry Pi Forums


the message shown when ssh'ing pi's not informative, , after seeing few hundred times wondered ubuntu style 'message of day' (motd), provides useful information when log on terminal interface

after research , lot of other sites, changed log on information this:
linux rp2 3.18.7+ #755 preempt thu feb 12 17:14:31 gmt 2015 armv6l

programs included debian gnu/linux system free software;
exact distribution terms each program described in the
individual files in /usr/share/doc/*/copyright.

debian gnu/linux comes absolutely no warranty, extent
permitted applicable law.
to this:
rp2-motd.png
message of day
rp2-motd.png (33.03 kib) viewed 695 times
idea came http://scotte.github.io/2014/03/a-better-dynamic-motd/, although implementation different , think more straightforward.
many of lines of code creating detailed messages such free memory, came site.

share how can done , discuss of issues. quite easy do, , following step step instructions takes few minutes.

overall approach use ubuntu's dynamic message of day program 'update-notifier-common' , installed program run-parts run series of scripts in folder, in name/number order create message of day part produced @ time of login , part produced in background.

there trade-off between preparing data in advance of logging in , presenting stale data , there trade-off between preparing data dynamically @ time of logging on , how long wait logged on.

scheme allows choose display @ login , parts have been prepared in advance , 'static' when log on , parts prepared dynamically.

there 2 folders containing scripts.
first folder '/etc/update/motd.d' contains scripts run @ login. of scripts dynamic, such 1 displays cpu , memory use, while others have been processed in advance, not slow down login process.
ones processed in advance generated scripts in second folder /etc/update-motd-static.d

second folder '/etc/update-motd-static.d' contains information either static or doesn't change often.

although second folder named static, contain information changes! had use name implied data not generated @ login - prepared, static @ time of login.

these scripts include relatively fixed information such pi's model , hostname , information not change rapidly, such available space on drives , package updates.

scripts in /etc/update-motd-static.d updated cron job in root's cron. have set run hourly, can choose interval. chose not update @ bootup delay boot process. information last run before shutdown still there , available. information on packages available update 1 likey out of date may have rebooted complete update, package information slowest create decided keep in static folder.

here step-by-step guide used on raspberry pi model b, running raspbian/linux version 3.18.7+
have tested on model b+

1. several steps require root access, become root
sudo su

2. install updater program
apt-get update
apt-get upgrade
apt-get install update-notifier-common

3. create 2 new folders in /etc folder
mkdir /etc/update-motd.d
mkdir /etc/update-motd-static.d

4. remove existing messages (read them first , decide if want keep backup copy before deleting them)
rm /run/motd.dynamic
rm /etc/motd
rm /etc/motd.tail

5. create symbolic link motd
motd generated @ each login in /run folder , not in /etc folder
the motd in /etc folder link /run/motd
ln -s /run/motd /etc/motd

6. create basic message elements. can create more of own later, these ones have prepared.
remember static means not updated when ssh / login pi.
the message box - part static, part dynamic (90-footer dynamic includes date & time)
00-header
90-footer
a couple of lines of system information (dynamic)
10-load-avg
a disk space message (static)
15-disk-space
a line or 2 updating packages (static)
20-packages
you can see numbers in file names control order run when
called run-parts

6a. create dynamic scripts in folder /etc/update-motd.d
use favorite editor - use vim. if use else, replace vim text editor.

cd /etc/update-motd.d

don't tempted add extension such .sh file names
'10-load-avg' work, '10-load-avg.sh' not work!

vim 10-load-avg
enter text:

code: select all

#!/bin/bash # # function place text @ left side of box , and put '#'s around left(){ sp=$(( 62 - ${#1} )) # put message (formatted left-side message) flm=" # $1"$(printf %"$sp"s)"#" } # # system information ## system load load=$(awk '{print $1}' /proc/loadavg) # ## memory use memuse=$(awk '/^memtotal:/ {total=$2} /^memfree:/ {free=$2} /^buffers:/ {buffers=$2} /^cached:/ {cached=$2} end { printf("%3.1f%%", (total-(free+buffers+cached))/total*100)}' /proc/meminfo) # ## time ut=$(awk '{$0=$1} {fs="."; $0=$0; print $1}' < /proc/uptime) # convert seconds days/hours/minutes days=$(($ut / 86400));rem=$(($ut-( $days * 86400 ))) hours=$(($rem / 3600));rem=$(($rem-( $hours * 3600 ))) mins=$(($rem / 60)) # # single / plural text if [ $days ==  0 ]; dtxt=""         elif [ $days == 1 ]; dtxt="$days day,"         else dtxt="$days days," fi # if [ $hours ==  0 ]; htxt=""         elif [ $hours == 1 ]; htxt="$hours hour and"         else htxt="$hours hours and" fi # if [ $mins ==  0 ]; mtxt=""         elif [ $mins == 1 ]; mtxt="$mins minute"         else mtxt="$mins minutes" fi uptime="$dtxt $htxt $mtxt" # ## number of running processes procs=$(/bin/ls -d /proc/[0-9]* | wc -l) # left "load: $load ... memory usage: $memuse ... processes: $procs" msg1="$flm" left "uptime: $uptime" msg2="$flm" # # end of pre-processing # echo -e "$msg1" echo -e "$msg2" echo " #                                                               #" 
save & quit editor

vim 90-footer
enter text:

code: select all

#!/bin/bash # # lower half of welcome header, current date/time # change format suit # # control message formatting function centers piece of text #  , puts '#'s around centre(){ sp1=$(( (63 - ( ${#1} )) /2 )) sp2=$sp1 # need space when total length 1 short (can't have half-spaces on both sides!) if [[ $(($sp1 + ${#1} + $sp2 )) < 63 ]]; sp2=$(($sp2+1));fi # put message (formatted centred message) fcm="#"$(printf %"$sp1"s)"$1"$(printf %"$sp2"s)"#" return 0 } # get/format date dt=`date "+%d-%b-%y, %h:%m"` # # call function create centered message centre "$dt" dt="$fcm" # # end of pre-processing # echo " #                                                               #" echo " $dt" echo " #                                                               #" echo " #################################################################" echo 
save , quit editor.

6b. create empty files output of 'static' scripts
touch 00-header
touch 15-disk-space
touch 20-packages

6c. make script files executable
chmod 0740 /etc/update-motd.d/*

6d. create static scripts in folder /etc/update-motd-static.d
cd /etc/update-motd-static.d

vim 00-header
enter text:

code: select all

#!/bin/bash # # top part of header system information # version 1.00 # anita2r may 2015 # ****************************************************************************** #   file can edited - 'do not edit' message appear @ top #              of output file '/etc/update-motd.d/00-header' #                         should not edited # ****************************************************************************** # if run file directly or through 'run-parts /etc/update-motd-static.d' #          output appear in /etc/update-motd.d/00-header #                            , not on screen # ****************************************************************************** # # control message formatting function centers piece of text #  , puts '#'s around centre(){ sp1=$(( (63 - ( ${#1} )) /2 )) sp2=$sp1 # need space when total length 1 short (can't have half-spaces on both sides!) if [[ $(($sp1 + ${#1} + $sp2 )) < 63 ]]; sp2=$(($sp2+1));fi # put message (formatted centred message) fcm="#"$(printf %"$sp1"s)"$1"$(printf %"$sp2"s)"#" return 0 } # # operating system details /proc/version osd=$(awk '{fs=" \("; $0=$0; print $1}' < /proc/version) # call function create formatted message centre "$osd" osd="$fcm" # # first processor information /proc/cpuinfo # awk adds line numbers, can handle multiple processors , take info first 1 pro=$(grep "model name" < /proc/cpuinfo | awk '{fs=":"; $0=$0; $0=$2;} {fs="\n"; $0=$0; print nr $1;}'| grep "1 ") # drop line number added in awk pro=${pro:2} # call function create formatted message centre "$pro" pro="$fcm" # # create machine name including hostname - if set hnm=$(cat /etc/hostname) if [ $hnm ]         hnm=$(cat /sys/firmware/devicetree/base/model)" - $hnm"         else hnm=$(cat /sys/firmware/devicetree/base/model) fi # call function create formatted message centre "$hnm" hnm="$fcm" # # end of pre-processing # out="/etc/update-motd.d/"$(basename $0) exec >${out} # echo "#!/bin/bash" echo "###########################################" echo "#         not edit file           #" echo "#        edit 00-header file          #" echo "# in /etc/update-motd-static.d folder #" echo "###########################################" # echo "cat << eof"  echo " #################################################################" echo " #                                                               #" echo " $hnm" echo " #                                                               #" echo " $pro" echo " $osd" echo " #                                                               #"  echo "eof" 
save , quit editor.

vim 15-disk-space
enter text:

code: select all

#!/bin/bash # # display partition usage if partition > 70% full # version 1.00 # anita2r may 2015 # ****************************************************************************** #   file can edited - 'do not edit' message appear @ top #              of output file '/etc/update-motd.d/15-disk-space' #                         should not edited # ****************************************************************************** # if run file directly or through 'run-parts /etc/update-motd-static.d' #          output appear in /etc/update-motd.d/15-disk-space #                            , not on screen # ****************************************************************************** # # control message formatting function places text #  @ left side of box , and puts '#'s around left(){ sp=$(( 62 - ${#1} )) flm=" # $1"$(printf %"$sp"s)"#" } # # partition information using 'df' - output information if usage excedes 70% ## attached devices if - reported /dev/sda1 etc. hd=$(df -l | grep /dev/sd | awk '{if (0+$5 > 70) print $1"at"$5" "}') ## sd card partitions sd=$(df -l | grep mmcblk | awk '{if (0+$5 > 70) print $1"at"$5" "}') p2=$(df / | grep root | awk '{if (0+$5 > 70) print $1"at"$5}') # # mmcblk0p2 appears /dev/root - replace 'root' 'mmcblk0p2' consistency p2=$(echo "$p2" | sed 's/root/mmcblk0p2/') # put messages , remove '/dev' prefixes  diskmsg=$(echo "$hd$sd$p2" | sed 's/\/dev\///g') # # $diskmsg empty (and hence 'false') if no partition on 70% full if [[ "$diskmsg" ]]                 left "the following partitions on 70% full:"         msg="$flm\n"         disk in $diskmsg                                 # put spaces around 'at' e.g. mmcblk0p1at75% > mmcblk0p1 @ 75%                 disk=$(echo "$disk" | sed 's/at/ @ /')                 left "  $disk"                 msg="$msg""$flm\n"         done         else         left "all partitions have @ least 30% free space"         msg="$flm\n" fi # # end of pre-processing # out="/etc/update-motd.d/"$(basename $0) exec >${out} # echo "#!/bin/bash" echo "###########################################" echo "#         not edit file           #" echo "#      edit 15-disk-space file        #" echo "# in /etc/update-motd-static.d folder #" echo "###########################################" # echo "cat << eof" echo -e  -n "$msg" echo " #                                                               #" echo "eof" 
save , quit editor.

vim 20-packages
enter text:

code: select all

#!/bin/bash # # package update information # version 1.00 # anita2r may 2015 # ****************************************************************************** #   file can edited - 'do not edit' message appear @ top #              of output file '/etc/update-motd.d/20-packages' #                         should not edited # ****************************************************************************** # if run file directly or through 'run-parts /etc/update-motd-static.d' #          output appear in /etc/update-motd.d/20-packages #                            , not on screen # ****************************************************************************** # # control message formatting function places text #  @ left side of box , and puts '#'s around left(){ sp=$(( 62 - ${#1} )) flm=" # $1"$(printf %"$sp"s)"#" } # # package update message msg1=$(/usr/lib/update-notifier/apt-check --human-readable) # '0' @ start of first message (if won't printed) zero=${msg1:0:1} # remove new lines in message msg1=$(echo $msg1 | tr '\n' ' ') # modify '0 updates security updates' message msg1=$(echo $msg1 | sed 's/0 updates security updates/none security updates/') # restart message (if any) msg2=$(/usr/lib/update-notifier/update-motd-reboot-required) # if [[ $zero > 0 ]]                 msg="$msg1"         left "$msg1"         msg="$flm"         if [[ $msg2 != "" ]]                                 left $msg1                 msg=$flm                 left $msg2                 msg="$msg\n$flm"         fi         else         left "there no updates waiting installed"         msg=$flm fi # # end of pre-processing # out="/etc/update-motd.d/"$(basename $0) exec >${out} # echo "#!/bin/bash" echo "###########################################" echo "#         not edit file           #" echo "#       edit 20-packages file         #" echo "# in /etc/update-motd-static.d folder #" echo "###########################################" # echo "cat << eof"  echo -e "$msg" echo "eof" 
save , quit editor.

6e. make script files executable
chmod 0740 /etc/update-motd-static.d/*

7. run update of 'static' files check work
run-parts /etc/update-motd-static.d
the time takes complete gives idea of how ssh login delayed if these scripts ran @ login time dynamic scripts.
output should in files of same name in /etc/update-motd.d folder

8. create cron job update 'static' data
crontab -e
add lines:
# update 'static' parts of message of day, every hour
0 * * * * run-parts /etc/update-motd-static.d
save/write/close crontab

note did root, in root's cron.
when running normal user, edit this, need sudo crontab -e

that's setup.
don't forget exit root , become normal user again

can test logging in again through ssh

notes
a. speeding dynamic content
followed suggestion section 'make dynamic content faster' in scotte's blog
http://scotte.github.io/2014/03/a-better-dynamic-motd/
not using structure: 'cat | awk', i.e. not spawing new process 'cat' , piping output awk. instead used, example, this:
ut=$(awk '{$0=$1} {fs="."; $0=$0; print $1}' /proc/uptime)
awk takes information in /proc/uptime directly file
compared this:
ut=$(cat /proc/uptime | awk '{$0=$1} {fs="."; $0=$0; print $1}')
took less half time run 1000 times : 36 seconds vs 85 seconds on model b single processor pi.

unlike scotte, used variable substitution var=$(...), rather var=`...` using backticks.
did consistency of style rest of scripts. didn't see difference in speed between 2 styles when testing example of each on 1000 repetitions.

b. can add additional information message of day:
b1. dynamic information, create new file in /etc/update-motd.d folder
number according want appear. use 1 of existing dynamic scripts template.

b2. static information requires occasional updating, add file /etc/update-motd-static.d folder.
use 1 of existing static files template.

c. output has been created echo statements, printf can used. it's choice.
kept echo consistency.
(i did use printf create spaces when positioning messages, not direct output of text)

d. information /proc
/proc folder 1 source of system information, information vary distribution distribution, if use these scripts on distributions other raspbian, you have make changes pre-processing part of script, extract required information. multiple processors affects data, example processor information may occur more once , code has devised obtain 1 copy of information. way start use 'cat'
e.g. cat/proc/uptime see there , devise plan extracting it.
found awk useful not extracts fields number, can count number of instances of match, printing matching information if condition met, such partitions @ >70% full.

e. implementations of motd include 99-footer file takes information /etc/motd.tail file
can't see value in this, didn't include it.
if need add additional information (dynamic or static), add appropriate file, such 40-more-info, or if want after main box number > 90: e.g. 95-after-the-box

g. disk space sd card
there 2 lines getting disk space use sd card partitions.
unlike standard drive partitions reported sdnx e.g. sda1, sd card partitions not reported 'df' utility mmcblkxpx e.g. mmcblk0p1, although appear in /dev
result 2 lines had used sd card information
enter df -l in terminal , see mean

h. if nothing appears or original information appears when login through ssh, in '/run' folder:
ls /run
if there file 'motd.new' means 1 of scripts in 'update-motd.d' folder has failed. try running sudo run-parts /etc/update-motd.d , see if throws out errors.
@ contents of motd.new
cat /run/motd.new
if there section of motd missing, errors in script or scripts should have generated section. in particular @ scripts see have been copied example code. vim, failure go insert mode before pasting in code, results in missing code @ start of script.

i. have fun - did

anita2r

very nice! --good job!




.


raspberrypi



Comments

Popular posts from this blog

opencv3, tbb and rasp pi 2 - Raspberry Pi Forums

small ethernet problem - Raspberry Pi Forums

Multithumb configuration params not working? - Joomla! Forum - community, help and support