RK3588-Firefly 可自定义修改终端登录显示的信息
准备工具:
1、开发板: Firefly-RK3588(或者选择Firefly的其他版本的开发板)
2、操作系统:Ubuntu 20.04
3、Module: MOTD
什么是MOTD:
motd:是英文缩写message of the day 。译文是:每日提示信息,问候报文。为什么要用MOTD?其实目的很简单,是提示进入系统的用户注意事项,或提示系统运行的概要信息让用户更好的了解系统。在Linux系统要实现自己的MOTD,首先需要认识/etc/motd文件。
/etc/motd文件有时不一定是个常规文本文件,也可能是一个软链接到某个特定的文件,如/var/run/motd。
通常一个标准的motd信息有以下内容:
1、欢迎信息,一般包括Linux发行版本名称,内核版本、操作系统位数
2、操作系统当前信息,如操作系统负载,进程数量,文件系统使用情况,当前用户登录数,内存(含swap)使用情况,IP地址
3、文档和帮助信息
4、可更新的软件包和可升级的安全补丁
由此可见,motd展示出来的一定是一个当前的信息,是一组固定时间下特定参数所对应的数值,而不是一成不变的信息,因此静态的文本文件不足以满足以上内容。
在Ubuntu中有update-motd来帮助系统管理员或用户实现这个功能。可执行的脚本位于/etc/update-motd.d/*下,在每次登录时以root身份由pam_motd调用,脚本运行的次序由run-parts(run scripts or programs in a directory,在一个目录里运行脚本或程序)的–lsbsysinit选项决定。pam_motd也支持不动态更新,只需要在其选项中添加noupdate即可。
远程登陆界面展示:
发现串口终端显示的系统登录信息是原先定制好的,展示了firefly的彩色艺术字,还有官方网址以及系统的相关信息。
在linux系统可以通过配置/etc/motd
文件来实现该功能,但是在Ubuntu系统中此方法无效,而是通过/var/run/motd.dynamic
来动态生成。
可以通过命令进行查看:
**注意:**直接修改该文件是无效的。
其实它是通过/etc/update-motd.d/
目录下的一系列脚本在开机后根据前缀数字顺序来执行生成的:
查看脚本内容:
可分别查看这三个脚本里面的内容并且修改代码
1、00-header 脚本
2、10-help-text 脚本
3、30-sysinfo 脚本(里面内容较多)
完整代码:
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
#
# DO NOT EDIT THIS FILE but add config options to /etc/default/armbian-motd
# generate system information
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
THIS_SCRIPT="sysinfo"
MOTD_DISABLE=""
STORAGE=/dev/sda1
SHOW_IP_PATTERN="^[ewr].*|^br.*|^lt.*|^umts.*"
CPU_TEMP_LIMIT=45
AMB_TEMP_LIMIT=40
[[ -f /etc/default/armbian-motd ]] && . /etc/default/armbian-motd
for f in $MOTD_DISABLE; do
[[ $f == $THIS_SCRIPT ]] && exit 0
done
# don't edit below here
function display() {
# $1=name $2=value $3=red_limit $4=minimal_show_limit $5=unit $6=after $7=acs/desc{
# battery red color is opposite, lower number
if [[ "$1" == "Battery" ]]; then local great="<"; else local great=">"; fi
if [[ -n "$2" && "$2" > "0" && (( "${2%.*}" -ge "$4" )) ]]; then
printf "%-14s%s" "$1:"
if awk "BEGIN{exit ! ($2 $great $3)}"; then echo -ne "\e[0;91m $2"; else echo -ne "\e[0;92m $2"; fi
printf "%-1s%s\x1B[0m" "$5"
printf "%-11s%s\t" "$6"
return 1
fi
} # display
function getboardtemp() {
if [ -f /etc/armbianmonitor/datasources/soctemp ]; then
read raw_temp </etc/armbianmonitor/datasources/soctemp 2>/dev/null
if [ ! -z $(echo "$raw_temp" | grep -o "^[1-9][0-9]*\.\?[0-9]*$") ] && (( $(echo "${raw_temp} < 200" |bc -l) )); then
# Allwinner legacy kernels output degree C
board_temp=${raw_temp}
else
board_temp=$(awk '{printf("%d",$1/1000)}' <<<${raw_temp})
fi
elif [ -f /etc/armbianmonitor/datasources/pmictemp ]; then
# fallback to PMIC temperature
board_temp=$(awk '{printf("%d",$1/1000)}' </etc/armbianmonitor/datasources/pmictemp)
fi
} # getboardtemp
function batteryinfo() {
# Battery info for Allwinner
mainline_dir="/sys/power/axp_pmu"
legacy_dir="/sys/class/power_supply"
if [[ -e "$mainline_dir" ]]; then
read status_battery_connected < $mainline_dir/battery/connected 2>/dev/null
if [[ "$status_battery_connected" == "1" ]]; then
read status_battery_charging < $mainline_dir/charger/charging
read status_ac_connect < $mainline_dir/ac/connected
read battery_percent< $mainline_dir/battery/capacity
# dispay charging / percentage
if [[ "$status_ac_connect" == "1" && "$battery_percent" -lt "100" ]]; then
status_battery_text=" charging"
elif [[ "$status_ac_connect" == "1" && "$battery_percent" -eq "100" ]]; then
status_battery_text=" charged"
else
status_battery_text=" discharging"
fi
fi
elif [[ -e "$legacy_dir/axp813-ac" ]]; then
read status_battery_connected < $legacy_dir/axp20x-battery/present
if [[ "$status_battery_connected" == "1" ]]; then
status_battery_text=" "$(awk '{print tolower($0)}' < $legacy_dir/axp20x-battery/status)
read status_ac_connect < $legacy_dir/axp813-ac/present
read battery_percent< $legacy_dir/axp20x-battery/capacity
fi
elif [[ -e "$legacy_dir/battery" ]]; then
if [[ (("$(cat $legacy_dir/battery/voltage_now)" -gt "5" )) ]]; then
status_battery_text=" "$(awk '{print tolower($0)}' < $legacy_dir/battery/status)
read battery_percent <$legacy_dir/battery/capacity
fi
fi
} # batteryinfo
function ambienttemp() {
# define where w1 usually shows up
W1_DIR="/sys/devices/w1_bus_master1/"
if [ -f /etc/armbianmonitor/datasources/ambienttemp ]; then
read raw_temp </etc/armbianmonitor/datasources/ambienttemp 2>/dev/null
amb_temp=$(awk '{printf("%d",$1/1000)}' <<<${raw_temp})
echo $amb_temp
elif [[ -d $W1_DIR && $ONE_WIRE == yes ]]; then
device=$(ls -1 $W1_DIR | grep -Eo '^[0-9]{1,4}' | head -1)
if [[ -n $device ]]; then
if [[ -d ${W1_DIR}${device}/hwmon/hwmon0 ]]; then hwmon=0; else hwmon=1; fi
read raw_temp < ${W1_DIR}${device}/hwmon/hwmon${hwmon}/temp1_input 2>/dev/null
amb_temp=$(awk '{printf("%d",$1/1000)}' <<<${raw_temp})
echo $amb_temp
fi
else
# read ambient temperature from USB device if available
if [[ ! -f /usr/bin/temper ]]; then
echo ""
return
fi
amb_temp=$(temper -c 2>/dev/null)
case ${amb_temp} in
*"find the USB device"*)
echo ""
;;
*)
amb_temp=$(awk '{print $NF}' <<<$amb_temp | sed 's/C//g')
echo -n "scale=1;${amb_temp}/1" | grep -oE "\-?[[:digit:]]+\.[[:digit:]]"
esac
fi
} # ambienttemp
#function get_ip_addresses() {
# # return up to 2 IPv4 address(es) comma separated
# hostname -I | tr " " "\n" | \
# grep -E "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" | \
# tail -n2 | sed ':a;N;$!ba;s/\n/,/g'
#} # get_ip_addresses
function get_ip_addresses() {
local ips=()
for f in /sys/class/net/*; do
local intf=$(basename $f)
# match only interface names starting with e (Ethernet), br (bridge), w (wireless), r (some Ralink drivers use ra<number> format)
if [[ $intf =~ $SHOW_IP_PATTERN ]]; then
local tmp=$(ip -4 addr show dev $intf | awk '/inet/ {print $2}' | cut -d'/' -f1)
# add both name and IP - can be informative but becomes ugly with long persistent/predictable device names
#[[ -n $tmp ]] && ips+=("$intf: $tmp")
# add IP only
[[ -n $tmp ]] && ips+=("$tmp")
fi
done
echo "${ips[@]}"
} # get_ip_addresses
function storage_info() {
# storage info
RootInfo=$(df -h /)
root_usage=$(awk '/\// {print $(NF-1)}' <<<${RootInfo} | sed 's/%//g')
root_total=$(awk '/\// {print $(NF-4)}' <<<${RootInfo})
StorageInfo=$(df -h $STORAGE 2>/dev/null | grep $STORAGE)
if [[ -n "${StorageInfo}" && ${RootInfo} != *$STORAGE* ]]; then
storage_usage=$(awk '/\// {print $(NF-1)}' <<<${StorageInfo} | sed 's/%//g')
storage_total=$(awk '/\// {print $(NF-4)}' <<<${StorageInfo})
fi
} # storage_info
# query various systems and send some stuff to the background for overall faster execution.
# Works only with ambienttemp and batteryinfo since A20 is slow enough :)
amb_temp=$(ambienttemp &)
ip_address=$(get_ip_addresses &)
batteryinfo
storage_info
getboardtemp
critical_load=$(( 1 + $(grep -c processor /proc/cpuinfo) / 2 ))
# get uptime, logged in users and load in one take
UptimeString=$(uptime | tr -d ',')
time=$(awk -F" " '{print $3" "$4}' <<<"${UptimeString}")
load="$(awk -F"average: " '{print $2}'<<<"${UptimeString}")"
users="$(awk -F" user" '{print $1}'<<<"${UptimeString}")"
case ${time} in
1:*) # 1-2 hours
time=$(awk -F" " '{print $3" hour"}' <<<"${UptimeString}")
;;
*:*) # 2-24 hours
time=$(awk -F" " '{print $3" hours"}' <<<"${UptimeString}")
;;
esac
# memory and swap
mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
memory_usage=$(awk '{printf("%.0f",(($2-($4+$6+$7))/$2) * 100)}' <<<${mem_info})
memory_total=$(awk '{printf("%d",$2/1024)}' <<<${mem_info})
swap_info=$(LC_ALL=C free -m | grep "^Swap")
swap_usage=$( (awk '/Swap/ { printf("%3.0f", $3/$2*100) }' <<<${swap_info} 2>/dev/null || echo 0) | tr -c -d '[:digit:]')
swap_total=$(awk '{print $(2)}' <<<${swap_info})
echo
echo -n "System information as of "
/bin/date
echo
# display info
display "System load" "${load%% *}" "${critical_load}" "0" "" "${load#* }"
printf "Up time: \x1B[92m%s\x1B[0m\t\t" "$time"
display "Local users" "${users##* }" "3" "2" ""
echo "" # fixed newline
display "Memory usage" "$memory_usage" "70" "0" " %" " of ${memory_total}MB"
display "Zram usage" "$swap_usage" "75" "0" " %" " of $swap_total""Mb"
printf "IP: "
printf "\x1B[92m%s\x1B[0m" "$ip_address"
echo "" # fixed newline
a=0;b=0;c=0
display "CPU temp" "$board_temp" $CPU_TEMP_LIMIT "0" "°C" "" ; a=$?
display "Ambient temp" "$amb_temp" $AMB_TEMP_LIMIT "0" "°C" "" ; b=$?
(( ($a+$b) >0 )) && echo "" # new line only if some value is displayed
display "Usage of /" "$root_usage" "90" "1" "%" " of $root_total"
display "storage/" "$storage_usage" "90" "1" "%" " of $storage_total"
display "Battery" "$battery_percent" "20" "1" "%" "$status_battery_text"
echo ""
echo ""
Firefly艺术字的修改:
关键就是这句 TERM=linux toilet -f standard -F gay Firefly
其中:
- TERM=linux设置终端类型为linux
- 然后使用toilet工具将普通的文本转换为艺术字,这是个有趣的小工具,用法如下:
注意:想要修改这三个脚本内容,需要提前修改文件的权限
$ sudo chmod a+w 00-header
修改完成后保存退出
再重新远程登陆下,发现字体已经被修改成功了。
还是比较有趣的!!!
相关文章
- iOS7中修改StatusBar的显示颜色
- 指定查找区间,查找学生姓名并显示是否修改成功
- Windows 文件夹修改为exe的原理和解决办法
- Eclipse 修改 创建的Jsp的默认格式
- 【问题解决方案】GitHub图片不显示的问题通过修改hosts解决
- 【Linux基础】linux下修改ls显示的时间格式
- fastadmin修改表的注释后怎样修改列表栏的名称
- imagemagick:修改图片的dpi(分辨率/Resolution)(ImageMagick 6.9.10)
- 让ERP downloaded product的description能够在CRM被修改
- RK3288 android7.1显示屏幕修改
- Android 11.0 12.0NavigationBarView 导航栏 左边显示的修改
- Android 10.0 导航栏横屏固定在底部显示的修改
- 查看修改swap空间大小
- django图片上传修改图片名称
- RK3399平台开发系列讲解(其他篇)1.6、UBOOT 中HDMI默认分辨率的修改【UBOOT上HDMI LOGO 显示代码分析】
- RK3399平台开发系列讲解(系统修改记录篇)1.20、system.img扩容
- intellij idea、webstorm或者vscode怎样显示每行代码的git版本信息?是谁修改的?什么时候修改的?查看代码行git/svn提交记录git blame好用的ide插件推荐
- Ansible 常用模块之文件内容修改 blockinfile|lineinfile
- macOS修改主机名和计算机名
- 最小化自动安装的Centos7修改完整中文显示