Example output:
Welcome to Debian 11 (bullseye) with Linux 5.10.0-26-cloud-amd64
System load: 5% Up time: 155 days 2:42
Memory usage: 16% of 455M IP: 172.31.43.181 10.235.101.1
Usage of /: 15% of 30G `
#!/bin/bash | |
# | |
# Copyright (c) Authors: https://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 | |
# any changes will be lost on board support package update | |
THIS_SCRIPT="header" | |
MOTD_DISABLE="" | |
. /etc/os-release | |
for f in $MOTD_DISABLE; do | |
[[ $f == $THIS_SCRIPT ]] && exit 0 | |
done | |
KERNELID=$(uname -r) | |
# Odroid N2 exception | |
[[ -f /proc/device-tree/model ]] && [[ -n $(tr -d '\000' < /proc/device-tree/model | grep ODROID | grep Plus) ]] && BOARD_NAME+="+" | |
TERM=linux toilet -f standard -F metal $(echo $BOARD_NAME | sed 's/Orange Pi/OPi/' | sed 's/NanoPi/NPi/' | sed 's/Banana Pi/BPi/') | |
echo -e "Welcome to \e[0;91mDebian ${VERSION}\x1B[0m with $([[ $BRANCH == edge ]] && echo -e "\e[0;91mbleeding\x1B[0m edge " )\e[0;91mLinux $KERNELID\x1B[0m" | |
# displaying status warnings | |
if [[ "$IMAGE_TYPE" != "stable" ]]; then | |
[[ "$IMAGE_TYPE" == "user-built" ]] && UNSUPPORTED_TEXT="built from trunk" | |
[[ "$IMAGE_TYPE" == "nightly" ]] && UNSUPPORTED_TEXT="untested automated build" | |
else | |
[[ "$BOARD_TYPE" == "csc" || "$BOARD_TYPE" == "tvb" ]] && UNSUPPORTED_TEXT="community creations" | |
[[ "$BOARD_TYPE" == "wip" ]] && UNSUPPORTED_TEXT="work in progress" | |
[[ "$BOARD_TYPE" == "eos" ]] && UNSUPPORTED_TEXT="end of life" | |
fi | |
if [[ -n $DISTRIBUTION_STATUS && $DISTRIBUTION_STATUS != supported ]]; then | |
[[ -n $UNSUPPORTED_TEXT ]] && UNSUPPORTED_TEXT+=" & " | |
UNSUPPORTED_TEXT+="unsupported ($DISTRIBUTION_CODENAME) userspace!" | |
fi | |
if [[ -n $UNSUPPORTED_TEXT ]]; then | |
echo -e "\e[0;91mNo end-user support: \x1B[0m$UNSUPPORTED_TEXT\n" | |
fi | |
#!/bin/bash | |
# | |
# Copyright (c) Authors: https://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" | |
# don't change default values - they are lost on upgrades. Use /etc/default/armbian-motd for your values | |
MOTD_DISABLE="" | |
PRIMARY_INTERFACE="eth0" | |
PRIMARY_DIRECTION="rx" | |
STORAGE=/dev/sda1 | |
HIDE_IP_PATTERN="^dummy0|^lo" | |
CPU_TEMP_LIMIT=60 | |
# Temperature offset in Celcius degrees | |
CPU_TEMP_OFFSET=0 | |
HDD_TEMP_LIMIT=60 | |
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 | |
# Include functions: | |
# getboardtemp() | |
# batteryinfo() | |
# ambienttemp() | |
source /usr/lib/armbian/armbian-allwinner-battery | |
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" -gt "0" && (( "${2%.*}" -ge "$4" )) ]]; then | |
printf "%-14s" "$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\x1B[0m" "$5" | |
printf "%-11s\t" "$6" | |
return 1 | |
fi | |
} # display | |
function get_ip_addresses() { | |
local ips=() | |
for f in /sys/class/net/*; do | |
local intf=$(basename $f) | |
# match only interface names "dummy0" and "lo" | |
if [[ $intf =~ $HIDE_IP_PATTERN ]]; then | |
continue | |
else | |
local tmp=$(ip -4 addr show dev $intf | grep -v "$intf:avahi" | awk '/inet/ {print $2}' | cut -d'/' -f1 | uniq) | |
# 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}) | |
if [[ -n "$(command -v smartctl)" ]]; then | |
DISK="${STORAGE::-1}" | |
storage_temp+=$(smartctl -l scttempsts $DISK 2> /dev/null | grep -i 'Current Temperature:' | awk '{print $(NF-1)}') | |
fi | |
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=80 | |
# get uptime, logged in users and load in one take | |
UPTIME=$(LC_ALL=C uptime) | |
UPT1=${UPTIME#*'up '} | |
UPT2=${UPT1%'user'*} | |
users=${UPT2//*','} | |
users=${users//' '} | |
time=${UPT2%','*} | |
time=${time//','} | |
time=$(echo $time | xargs) | |
load=${UPTIME#*'load average: '} | |
load=${load//','} | |
load=$(echo $load | cut -d" " -f1) | |
[[ $load == 0.0* ]] && load=0.10 | |
cpucount=$(grep -c processor /proc/cpuinfo) | |
load=$(awk '{printf("%.0f",($1/$2) * 100)}' <<< "$load $cpucount") | |
# 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}) | |
mem_info=$(echo $mem_info | awk '{print $2}') | |
memory_total=$(( mem_info / 1024 )) | |
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}) | |
# display info | |
display "System load" "${load%% *}" "${critical_load}" "0" "%" "" | |
printf "Up time: \x1B[92m%s\x1B[0m\t" "$time" | |
display "Local users" "${users##* }" "3" "2" "" | |
echo "" # fixed newline | |
if [[ ${memory_total} -gt 1000 ]]; then | |
memory_total=$(awk '{printf("%.2f",$1/1024)}' <<<${memory_total})"G" | |
else | |
memory_total+="M" | |
fi | |
if [[ ${swap_total} -gt 500 ]]; then | |
swap_total=$(awk '{printf("%.2f",$1/1024)}' <<<${swap_total})"G" | |
else | |
swap_total+="M" | |
fi | |
display "Memory usage" "$memory_usage" "70" "0" "%" " of ${memory_total}" | |
display "Zram usage" "$swap_usage" "75" "0" "%" " of ${swap_total}" | |
printf "IP: " | |
printf "\x1B[92m%s\x1B[0m" "$ip_address" | |
echo "" # fixed newline | |
display "CPU temp" "$board_temp" $CPU_TEMP_LIMIT "0" "°C" "" | |
display "Ambient temp" "$amb_temp" $AMB_TEMP_LIMIT "0" "°C" "" | |
display "Usage of /" "$root_usage" "90" "1" "%" " of $root_total" | |
echo "" # fixed newline | |
a=0 | |
display "storage/" "$storage_usage" "90" "1" "%" " of $storage_total" ; a=$((a+$?)) | |
display "storage temp" "$storage_temp" $HDD_TEMP_LIMIT "0" "°C" "" ; a=$((a+$?)) | |
display "Battery" "$battery_percent" "20" "1" "%" "$status_battery_text" ; a=$((a+$?)) | |
(( $a > 0 )) && echo "" # new line only if some value is displayed | |
line=0 | |
if [[ -n "$PRIMARY_INTERFACE" ]] && vnstat -i "$PRIMARY_INTERFACE" &> /dev/null; then | |
traffic=$(vnstat -i $PRIMARY_INTERFACE --oneline | cut -d";" -f4,5) | |
traffic_rx=$(echo $traffic | cut -d";" -f1,1 | sed -r 's/([0-9]+\.[0-9]{1})[0-9]*/\1/') | |
traffic_tx=$(echo $traffic | cut -d";" -f2,2 | sed -r 's/([0-9]+\.[0-9]{1})[0-9]*/\1/') | |
[[ "$traffic" == *"Not enough"* ]] && { traffic_tx="n/a "; traffic_rx="n/a "; } | |
case $PRIMARY_DIRECTION in | |
tx) | |
printf "TX today: \x1B[92m%s\x1B[0m \t" "$traffic_tx" | |
line=$((line+1)) | |
;; | |
rx) | |
printf "RX today: \x1B[92m%s\x1B[0m \t" "$traffic_rx" | |
line=$((line+1)) | |
;; | |
both) | |
printf "TX today: \x1B[92m%s\x1B[0m \t" "$traffic_tx" | |
printf "RX today: \x1B[92m%s\x1B[0m \t" "$traffic_rx" | |
line=$((line+1)) | |
;; | |
*) #off or whatever | |
;; | |
esac | |
fi | |
if [[ $(command -v zpool) ]]; then | |
zpoolstatus="$(zpool status </dev/stdin 2>&1 )" | |
if [[ -n $(echo $zpoolstatus | grep 'not loaded') ]]; then | |
: | |
elif [[ -n $(echo $zpoolstatus | grep 'degraded\|OFFLINE') ]]; then | |
printf "ZFS pool: " | |
echo -ne "\e[0;91mDegraded\x1B[0m" | |
line=$((line+1)) | |
elif [[ -n $(echo $zpoolstatus | grep 'no pools available') ]]; then | |
printf "ZFS pool: " | |
echo -ne "n/a" | |
line=$((line+1)) | |
else | |
printf "ZFS pool: " | |
echo -ne "\e[0;92mOnline\x1B[0m" | |
line=$((line+1)) | |
fi | |
fi | |
[[ $line -ne 0 ]] && echo "" | |
echo "" |