-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2ca7167
Showing
9 changed files
with
402 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2021 AA | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
## MOTD | ||
Customized dynamic Message of the Day (MOTD) for Raspberry Pi | ||
|
||
### Preview | ||
![WithCount](https://user-images.githubusercontent.com/11185794/132077317-0513309b-2968-46f1-954f-4e225bfa49a6.png) | ||
|
||
![WithoutCount](https://user-images.githubusercontent.com/11185794/132077322-32c33c50-1a81-4d26-9be1-15c5284c161a.png) | ||
# | ||
### Intro | ||
Many folks use Raspberry Pi as headless (without display) system. If you use SSH to connect to your Raspberry Pi more often and interested in changing the MOTD (message of the day), this might be the one you were looking for. There are many options available for customized motd on the web with and without ascii art. **The goal was to create a simple, attractive, swift and useful motd**. | ||
<br/> | ||
|
||
I prefer updating my OS manually. After transition from Ubuntu to Raspberry Pi OS, lack of seeing the number of available updates on motd was the triggering point to develop this motd. Very few csutom motd on the web for Raspberry Pi OS shows the number of available updates. They use `apt-check` utility, which was removed form Debian long ago. Ubuntu uses the same utility to show package count on motd. I used `apt-get` to parse the required information. | ||
<br/> | ||
|
||
The process I used for the motd is the same as Raspberry Pi OS OR Ubuntu uses to show the motd dynamically. There is no third party package or tool used. It is written in bash and executes using the same mechanism as the default motd. There are multiple commands for retrieving the same information. I tested various commands for each info and used the ones that took least amount of time. This dynamic motd takes approximately 1 sec or less after entering password. This is the fastest you can get with all the information it is displaying. | ||
<br/> | ||
|
||
#### Specs: | ||
> Raspberry Pi 4 Model B • 2GB Memory • raspios-buster-arm64-lite | ||
> System & Distro I used for build & test. It should work on other specs as well. | ||
# | ||
### Steps | ||
#### ⮞ Remove Default MOTD | ||
|
||
* Delete `/etc/motd` file. This file contains the static text about Debian GNU/Linux liability. You can check the contents of the file with command `sudo nano /etc/motd`. Alternatively you can keep a backup of this file at some place. | ||
> **Delete motd file:** | ||
> `sudo rm /etc/motd` | ||
* Delete `/etc/update-motd.d/10-uname` file. This file prints the OS version dynamically to the default message. We will print a trimmed down version of OS through our new customized motd. | ||
> **Delete 10-uname file:** | ||
> `sudo rm /etc/update-motd.d/10-uname` | ||
* Modify `/etc/ssh/sshd_config` file. This file prints last login timestamp and location. We will print last login timestamp and location through our new customized motd. | ||
> **Edit sshd_config file:** | ||
> `sudo nano /etc/ssh/sshd_config` | ||
> Find the line `#PrintLastLog yes` Replace it with `PrintLastLog no` | ||
> Save sshd_config file [Ctrl+O] & Exit nano [Ctrl+X] | ||
> Restart sshd process `sudo systemctl restart sshd` | ||
# | ||
> **_NOTE:_** | ||
> At this point we completely removed the default motd. You can reconnect using ssh and if you followed the steps correctly you will not see any motd. | ||
# | ||
|
||
#### ⮞ Implement New MOTD | ||
|
||
* Copy `10-welcome` & `15-system` files from this repo folder `update-motd.d` to Raspberry Pi OS folder `/etc/update-motd.d` Make sure these files are under the user:group of root and they are executable. You can **either** use WinSCP or wget to copy/download these files to tmp folder and then move them to `/etc/update-motd.d` **or** create empty files in `/etc/update-motd.d` using touch and copy/paste the contents of corresponding file in it. | ||
|
||
> **Change ownership of files [If needed]:** | ||
> `sudo chown root:root /etc/update-motd.d/10-welcome` | ||
> `sudo chown root:root /etc/update-motd.d/15-system` | ||
> **Create empty files to copy/paste contents [If needed]:** | ||
> `sudo touch /etc/update-motd.d/10-welcome` | ||
> `sudo touch /etc/update-motd.d/15-system` | ||
> **Make files executable:** | ||
> `chmod +x /etc/update-motd.d/10-welcome` | ||
> `chmod +x /etc/update-motd.d/15-system` | ||
> If everything is done properly it will look something like this. Ignore `20-update` file for now we will create it in next step: | ||
> ![update-motd_files](https://user-images.githubusercontent.com/11185794/132084515-5b41d9fb-5e84-4c1d-8a2f-7d7cd9c5e671.png) | ||
* Create third file `/etc/update-motd.d/20-update` as empty file using touch | ||
> **Create file and make it executable:** | ||
> `sudo touch /etc/update-motd.d/20-update` | ||
> `chmod +x /etc/update-motd.d/20-update` | ||
# | ||
> **_NOTE:_** | ||
> If you noticed all the files we have created/copied so far have filenames starting with a number. Dynamic contents of the motd are created by PAM (Pluggable Authentication Module) running bash files from /etc/update-motd.d folder. The files are read in number order and do not need a file extension. In the default motd it was executing 10-uname file to show the OS version which we deleted earlier. | ||
# | ||
|
||
* In this step we will create static contents of our new motd. This is not entirely static, PAM will execute this information from bash file that has static contents. Static file is created from dynamic file using cronjob once a day. It is done this way to minimize startup delay. If I keep it completely dynamic (how I initially did and it was easier), the startup delay between entering the password and seeing the prompt is approximately 3-4 seconds. | ||
* Create a folder `/etc/update-motd-static.d` Even though this folder contains the dynamic file that will generate the static file `/etc/update-motd.d/20-update` I am calling it `update-motd-static.d` for easier distinction (You can name it whatever you prefer and use the same name in automation tasks) | ||
> **Create folder:** | ||
> `sudo mkdir /etc/update-motd-static.d/` | ||
* Copy `20-update` file from this repo folder `update-motd-static.d` to this newly created folder `/etc/update-motd-static.d` Make sure file is under the user:group of root and it is executable. You can **either** use WinSCP or wget to copy/download this file to tmp folder and then move it to `/etc/update-motd-static.d` **or** create empty file in `/etc/update-motd-static.d` using touch and copy/paste the contents of corresponding file in it. | ||
|
||
> **Change ownership of file [If needed]:** | ||
> `sudo chown root:root /etc/update-motd-static.d/20-update` | ||
> **Create empty file to copy/paste contents [If needed]:** | ||
> `sudo touch /etc/update-motd-static.d/20-update` | ||
> **Make file executable:** | ||
> `chmod +x /etc/update-motd-static.d/20-update` | ||
> If everything is done properly it will look something like this: | ||
> ![update-motd-static_files](https://user-images.githubusercontent.com/11185794/132091200-e960ac30-4985-447a-9c26-5878f2514c6e.png) | ||
|
||
* Execute this file. This process will update the static file `/etc/update-motd.d/20-update` with the number of pending updates (if any). We will automate this process through cronjob later. | ||
> **Execute file:** | ||
> `sudo run-parts /etc/update-motd-static.d` | ||
# | ||
> **_NOTE:_** | ||
> At this point we implemented our new motd, pending few automations. Let's test our new motd. It will verify that everything we did so far is working properly. There are multiple ways to test **either** you can reconnect using ssh **or** run the new motd from the same shell. If you followed the steps correctly you will see new motd something similar to the initial preview of this guide. | ||
> > **Execute motd from the same shell:** | ||
> > `sudo run-parts /etc/update-motd.d` | ||
# | ||
|
||
#### ⮞ Automation | ||
|
||
* We are almost done. We need to automate the process of finding pending OS updates count. I did it through a cronjob which runs once a day. You can change the time and frequency based on your requirements, once a day serves my purpose very well. Below cronjob will find the count of pending OS updates once a day at 8:00pm and update it in the motd. | ||
> **Create cronjob:** | ||
> Open crontab for root `sudo crontab -e` | ||
> Add below 2 lines at the end of the crontab file, **save** & close the editor | ||
> ``` | ||
> # MOTD - Update '20-update' file - Once A Day At 8:00PM | ||
> 0 20 * * * run-parts /etc/update-motd-static.d | ||
> ``` | ||
# | ||
> **_NOTE:_** | ||
> If this is the first time you are creating a cronjob. It will ask for your preferred editor, I use nano, you can choose your preferred one. | ||
# | ||
* Last step. We need to update the pending updates count in motd as soon as we update the OS. With this new motd mechanism it will be updated at the next execution of cronjob. Let's assume you update your system manually by running commands `sudo apt update` & `sudo apt full-upgrade`. **We need to run another command after this** `sudo run-parts /etc/update-motd-static.d` It will reset the update count in motd as soon as we are done with OS update. Whatever your preferred way to update the OS, run this command at the very end. | ||
* I update OS manually using a bash script `update.sh` after seeing pending updates in motd. This script takes care of everything that includes **update OS, cleanup and update motd count**. `update.sh` is available in the repo under folder `update-os` along with a screenshot of what it will do upon execution. It is well documented. **Open and check the commands first before execution, if you need all of them**. Feel free to modify it according to your requirement. | ||
You can add switch -y to `sudo apt full-upgrade` command if you want to bypass the yes/no prompt. I prefer not to have it as a last chance to review if I want to update or not. I do cleanup as well in this script using `sudo apt --purge autoremove` & `sudo apt clean`, you can remove them if you prefer not to run these after OS update. | ||
# | ||
> **_NOTE:_** | ||
> We are done. If you are not seeing the exact colors in your motd as shown in the preview, check the Putty section below for color scheme. | ||
# | ||
### Scripts Info | ||
#### ⮞ /etc/update-motd.d/10-welcome | ||
> Bash script displays the welcome user message along with current timestamp and OS version. | ||
#### ⮞ /etc/update-motd.d/15-system | ||
> Script shows various details of the system. It includes system temperature, memory, running processes and few more. I trimmed down on some of the labels, like I used `Procs` for `Processes`, `Temp` for `Temperature`, `Last` for `Last Login`. You can use full labels according to your liking and arrange them accordingly. | ||
#### ⮞ /etc/update-motd.d/20-update | ||
> This is the static script. It is generated by `/etc/update-motd-static.d/20-update` to show the number of available updates. | ||
#### ⮞ /etc/update-motd-static.d/20-update | ||
> Script calculates the number of available updates and generates the static file for motd display. It can be expanded to show the number of security updates separately like Ubuntu. My requirement was to see the total number only. | ||
# | ||
### PuTTY | ||
I use slight modification of `Liquid Carbon` PuTTY theme from [AlexAkulov](https://github.com/AlexAkulov/putty-color-themes/blob/master/23.%20Liquid%20Carbon.reg). Modified theme `Liquid Carbon Mod.reg` is available under this repo folder `putty` along with screenshots of PuTTY settings. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Windows Registry Editor Version 5.00 | ||
|
||
[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\Default%20Settings] | ||
"Colour0"="175,194,194" | ||
"Colour1"="255,255,255" | ||
"Colour2"="48,48,48" | ||
"Colour3"="48,48,48" | ||
"Colour4"="48,48,48" | ||
"Colour5"="203,137,5" | ||
"Colour6"="20,20,20" | ||
"Colour7"="20,20,20" | ||
"Colour8"="255,48,48" | ||
"Colour9"="255,48,48" | ||
"Colour10"="85,154,112" | ||
"Colour11"="85,154,112" | ||
"Colour12"="204,172,0" | ||
"Colour13"="204,172,0" | ||
"Colour14"="0,153,204" | ||
"Colour15"="0,153,204" | ||
"Colour16"="204,105,200" | ||
"Colour17"="204,105,200" | ||
"Colour18"="122,196,204" | ||
"Colour19"="122,196,204" | ||
"Colour20"="188,204,204" | ||
"Colour21"="188,204,204" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
## PuTTY Settings | ||
|
||
### Colors | ||
* Make sure you have 256 colour mode enabled. | ||
![putty_256_color](https://user-images.githubusercontent.com/11185794/132567767-2bc209c8-5526-410e-96b0-c6c75b94914a.png) | ||
# | ||
### Font | ||
* Consolas - 10 | ||
![putty_font](https://user-images.githubusercontent.com/11185794/132568229-f49dea53-0552-427e-9bc8-9b9bcfc44389.png) | ||
# | ||
### Character Set | ||
* UTF-8 should be enabled. | ||
![putty_UTF-8](https://user-images.githubusercontent.com/11185794/132568242-f0cf1609-cd47-4e09-a333-d585996a14d4.png) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#!/bin/bash | ||
|
||
function color (){ | ||
echo "\e[$1m$2\e[0m" | ||
} | ||
|
||
function setCountColor (){ | ||
local input=$1 | ||
countColor="30;48;5;242" | ||
|
||
if [ $input == 0 ]; then | ||
countColor="30;48;5;242" | ||
else | ||
countColor="30;48;5;71" | ||
fi | ||
} | ||
|
||
function msgFormat (){ | ||
local input=$1 | ||
local packagesPlural="s" | ||
|
||
if [[ $input -eq 0 || $input -eq 1 ]]; then | ||
packagesPlural="" | ||
fi | ||
echo "package$packagesPlural" | ||
} | ||
|
||
msgColor="30;38;5;103" | ||
|
||
# Count | ||
sudo apt-get update --quiet=2 | ||
pkgCount="$(apt-get -s dist-upgrade | grep -Po '^\d+(?= upgraded)')" | ||
setCountColor "$pkgCount" | ||
|
||
# Message | ||
msgHeader="$(color $msgColor ⮞)" | ||
msgCount="$(color $countColor " $pkgCount ")" | ||
msgLabel="$(color $msgColor "$(msgFormat $pkgCount) can be upgraded")" | ||
|
||
updateMsg=" $msgHeader $msgCount $msgLabel" | ||
|
||
# Output To Dynamic File | ||
OUT="/etc/update-motd.d/"$(basename $0) | ||
exec >${OUT} | ||
# | ||
echo "#!/bin/bash" | ||
echo "####################################################" | ||
echo "# DO NOT EDIT THIS FILE #" | ||
echo "# EDIT [20-update] In [/etc/update-motd-static.d/] #" | ||
echo "####################################################" | ||
# | ||
echo "cat <<EOF" | ||
echo -e "\n$updateMsg\n" | ||
echo "EOF" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#!/bin/bash | ||
|
||
#clear | ||
|
||
function color (){ | ||
echo "\e[$1m$2\e[0m" | ||
} | ||
|
||
function findDeviceModel (){ | ||
deviceName="" | ||
local deviceModel=$(tr -d '\0' < /sys/firmware/devicetree/base/model) | ||
local hostName=$(hostname) | ||
|
||
if [ $hostName ]; then | ||
deviceName="$deviceModel - $hostName" | ||
else | ||
deviceName="$deviceModel" | ||
fi | ||
} | ||
|
||
deviceColor="30;48;5;249" | ||
greetingsColor="30;38;5;103" | ||
userColor="30;48;5;67" | ||
me=$(logname) | ||
findDeviceModel | ||
|
||
# Device Info | ||
deviceLabel=" $(color $deviceColor " $deviceName ")" | ||
|
||
# Greetings | ||
me="$(color $userColor " $me ")" | ||
greetings="$(color $greetingsColor " ⮞ Welcome »") $me\n" | ||
greetings="$greetings$(color $greetingsColor " ⮞ $(date +"%a %b %d %Y, %I:%M:%S %p")")\n" | ||
|
||
# OS | ||
greetings="$greetings$(color $greetingsColor " ⮞ $(uname -srm)")" | ||
|
||
echo -e "\n$deviceLabel" | ||
echo -e "\n$greetings" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#!/bin/bash | ||
|
||
function color (){ | ||
echo "\e[$1m$2\e[0m" | ||
} | ||
|
||
function sec2time (){ | ||
local input=$1 | ||
|
||
((days=input/86400)) | ||
((input=input%86400)) | ||
((hours=input/3600)) | ||
((input=input%3600)) | ||
((mins=input/60)) | ||
|
||
local daysPlural="s" | ||
local hoursPlural="s" | ||
local minsPlural="s" | ||
|
||
if [[ $days -eq 0 || $days -eq 1 ]]; then | ||
daysPlural="" | ||
fi | ||
if [[ $hours -eq 0 || $hours -eq 1 ]]; then | ||
hoursPlural="" | ||
fi | ||
if [[ $mins -eq 0 || $mins -eq 1 ]]; then | ||
minsPlural="" | ||
fi | ||
echo "$days day$daysPlural $hours hr$hoursPlural $mins min$minsPlural" | ||
} | ||
statsLabelColor="30;38;5;143" | ||
bulletColor="30;38;5;241" | ||
infoColor="30;38;5;74" | ||
dimInfoColor="37;0;2" | ||
me=$(logname) | ||
|
||
# Last Login | ||
read loginIP loginDate <<< $(last $me --time-format iso -2 | awk 'NR==1 { print $3,$4 }') | ||
if [[ $loginDate == *T* ]]; then | ||
login="$(date -d $loginDate +"%a %b %d %Y, %I:%M %p") $(color $dimInfoColor "» $loginIP")" | ||
else | ||
# First Login | ||
login="None" | ||
fi | ||
|
||
# Stats | ||
label1="$login" | ||
label1="$(color $statsLabelColor "Last") $(color $bulletColor "····")$(color $statsLabelColor "›") $(color $infoColor "$label1")" | ||
|
||
label2="$(vcgencmd measure_temp | cut -c "6-9")°C" | ||
label2="$(color $statsLabelColor "Temp") $(color $bulletColor "···")$(color $statsLabelColor "›") $(color $infoColor $label2)" | ||
|
||
uptime="$(sec2time $(cut -d "." -f 1 /proc/uptime))" | ||
uptime="$uptime $(color $dimInfoColor "» $(date -d "@"$(grep btime /proc/stat | cut -d " " -f 2) +"%m-%d-%y %H:%M")")" | ||
|
||
label3="$uptime" | ||
label3="$(color $statsLabelColor "Uptime") $(color $bulletColor "··")$(color $statsLabelColor "›") $(color $infoColor "$label3")" | ||
|
||
label4="$(awk '{print $1}' /proc/loadavg)" | ||
label4="$(color $statsLabelColor "Load") $(color $bulletColor "···")$(color $statsLabelColor "›") $(color $infoColor $label4)" | ||
|
||
label5="$(df -h ~ | awk 'NR==2 { printf "%sB / %sB \e[30;38;5;144m» Free: %sB\e[0m",$3,$2,$4; }')" | ||
label5="$(color $statsLabelColor "Disk") $(color $bulletColor "····")$(color $statsLabelColor "›") $(color $infoColor "$label5")" | ||
|
||
label6="$(/bin/ls -d /proc/[0-9]* | wc -l)" | ||
label6="$(color $statsLabelColor "Procs") $(color $bulletColor "··")$(color $statsLabelColor "›") $(color $infoColor $label6)" | ||
|
||
label7="$(free -h --si | awk 'NR==2 { printf "%sB / %sB \e[30;38;5;144m» Free: %sB\e[0m",$3,$2,$4; }')" | ||
label7="$(color $statsLabelColor "Memory") $(color $bulletColor "··")$(color $statsLabelColor "›") $(color $infoColor "$label7")" | ||
|
||
label8="$(hostname -I)" | ||
label8="$(color $statsLabelColor "IP") $(color $bulletColor "·····")$(color $statsLabelColor "›") $(color $infoColor $label8)" | ||
|
||
echo | ||
# Two Entries Per Line | ||
echo -e " $label2\r $label1" | ||
echo -e " $label4\r $label3" | ||
echo -e " $label6\r $label5" | ||
echo -e " $label8\r $label7" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## OS Update Script Preview | ||
![UpdateScript](https://user-images.githubusercontent.com/11185794/132078145-c45cef75-6a3f-49f6-bee6-2415674f8820.png) | ||
|
Oops, something went wrong.