#!/bin/bash # These global variables can be overridden by config # Name of the pony PONY=random # What info to show (must have a function defined as ponyget_* to work) INFO=(User Hostname IP Distro Kernel Uptime Load Shell Packages CPU Threads RAM Swap Disk) # File system type to show disk usage (default/empty=all) (see df for specific values) FSTYPE= # Interface to get the IP address from IP_INTERFACE="eth0" function ponyget_Shell() { echo "$SHELL" } function ponyget_User() { whoami } function ponyget_Distro() { lsb_release -isr | paste "-d " - - } function pccolor() { local color="32"; if [ "$1" -gt 66 ] then color="31" elif [ "$1" -gt 33 ] then color="33" fi echo -e "\x1b[$color;1m" } function ponyget_RAM() { local ramtable=$(free -h | head -n -1) local used=$(echo "$ramtable" | tail -n 1 | sed -r "s/ +/\t/g" | cut -f 3) local total=$(echo "$ramtable" | sed -n 2p | sed -r "s/ +/\t/g" | cut -f 2) ramtable=$(free -m | head -n -1) local used_M=$(echo "$ramtable" | tail -n 1 | sed -r "s/ +/\t/g" | cut -f 3) local total_M=$(echo "$ramtable" | sed -n 2p | sed -r "s/ +/\t/g" | cut -f 2) let percent="$used_M * 100 / $total_M" echo -e "$(pccolor $percent)$used\x1b[0m / $total" } function ponyget_Swap() { local swaptable=$(free -h | grep Swap) local used=$(echo "$swaptable" | sed -r "s/ +/\t/g" | cut -f 3) local total=$(echo "$swaptable" | sed -r "s/ +/\t/g" | cut -f 2) swaptable=$(free -m | grep Swap) local used_M=$(echo "$swaptable" | sed -r "s/ +/\t/g" | cut -f 3) local total_M=$(echo "$swaptable" | sed -r "s/ +/\t/g" | cut -f 2) let percent="$used_M * 100 / $total_M" echo -e "$(pccolor $percent)$used\x1b[0m / $total" } function ponyget_Kernel() { uname -r -m } function ponyget_Hostname() { hostname } function ponyget_CPU() { cat /proc/cpuinfo | grep "model name" | head -n 1 | sed -r "s/model name\s: //" } function ponyget_Threads() { nproc --all } function ponyget_CPU_Usage() { printf %.1f%% "$(top -b -n1 | grep "Cpu(s):" | sed -r -e "s/^[^0-9]+//" -e "s/[^0-9]+,\s+/ + /g" -e "s/[^0-9]+$//" | cut -d ' ' -f 1-5 | bc)" } function ponyget_CPU_Temperature() { echo "$(echo "scale=1; $(cat /sys/devices/virtual/thermal/thermal_zone0/temp) / 1000" | bc) C" } function ponyget_Uptime() { uptime | grep -oE "up.*user" | \ sed -r -e "s/up\s*(.+),\s*[0-9]+\s*user/\1/" -e "s/\s+/ /g" } function ponyget_Load() { uptime | sed -r -e "s/.*load average:\s*//" } function ponyget_Packages() { if which dpkg &>/dev/null then dpkg --get-selections | grep -v deinstall | wc -l elif which rpm &>/dev/null then rpm -qa | wc -l elif which pacman &>/dev/null then pacman -Q | wc -l fi } function ponyget_Disk() { local dfoption=$FSTYPE [ "$dfoption" ] && dfoption="-t $FSTYPE" local diskusage=$(df -lh $dfoption -x overlay -x tmpfs -x devtmpfs --total | tail -n 1 | sed -r "s/ +/\t/g" ) local used=$(echo "$diskusage" | cut -f 3) local total=$(echo "$diskusage" | cut -f 2) local percent=$(echo "$diskusage" | cut -f 5 | sed s/%// ) echo -e "$(pccolor $percent)$used\x1b[0m / $total" } function ponyget_Containers() { local active="$(lxc-ls --active | wc -l)" local total="$(lxc-ls | wc -l)" local color=32 if [ "$active" -lt "$total" ] then color=31 fi echo -e "\x1b[$color;1m$active\x1b[0m / $total active" } function ponyget_IP() { [ -z "$1" ] && inet="inet" || inet="$1" ip -o addr | grep -vE "lo\s+inet" | grep -F "$IP_INTERFACE" | grep -Po "$inet\s+\K[^/]+" | xargs echo } function ponyget_IPv6() { ponyget_IP inet6 } function bold() { echo -en "\x1b[1m${*}\x1b[22m" } function underline() { echo -en "\x1b[4m${*}\x1b[24m" } function title() { echo bold ${*} echo } function help() { title NAME echo -e "\t$(bold $0) - show a pony and some system information" title SYNOPSIS echo -e "\t$(bold $0) [$(bold --pony) $(underline pony)|$(bold -p)$(underline pony)] [$(bold --info) $(underline id)|$(bold -i)$(underline id)...]" echo -e "\t$(bold $0) $(bold help)|$(bold --help)|$(bold -h)" title OPTIONS echo -e "\t$(bold --pony) $(underline pony), $(bold -p)$(underline pony)" echo -e "\t\tSelect a pony (default: $PONY)." echo echo -e "\t$(bold --info) $(underline id), $(bold -i)$(underline id)" echo -e "\t\tShow the given info (default: ${INFO[@]})." echo -e "\t\tThis option supports multiples IDs separated by commas, spaces or colons." echo -e "\t\tAvailable IDs:" declare -F | grep ponyget_ | sed "s/declare -f ponyget_/\t\t * /" echo echo -e "\t$(bold --list), $(bold --list-ponies)" echo -e "\t\tShows a list of possible values for $(bold --pony)." title CONFIGURATION echo -e "\tYou can override $(bold PONY) and $(bold INFO) in the config files." echo -e "\tConfiguration files:" echo -e "\t * $(underline PREFIX)$(bold /share/ascii-pony/systempony.conf) (system)" echo -e "\t * $(bold ~/.systempony) (user)" echo } function list_ponies() { ponydir=$(get_data_file "rendered/ansi/") echo random find "$ponydir" -name '*.ansi' -exec basename {} .ansi \; | sort } function select_info() { INFO=($(echo "${*}" | column -t -s:,)) } SELFDIR=$(dirname $(readlink -se "${BASH_SOURCE[0]}")) function get_data_file() { if [ -e "$SELFDIR/$1" ] then # Not installed echo "$SELFDIR/$1" elif [ -e "$SELFDIR/../share/ascii-pony/$1" ] then # Installed with PREFIX=$SELFDIR/.. echo "$SELFDIR/../share/ascii-pony/$1" fi } # Returns the number of displayed characters, ignoring color codes function strlen_color() { echo -n "$1" | sed -r 's/\x1b\[[0-9;]+m//g' | wc -c } # Truncates a string function truncate_color() { local length="$(strlen_color "$1")" local target="$2" if [ "$length" -gt "$target" ] then let cut="$target-$length" echo -n "$1" | head -c $cut return fi echo "$1" } # Read global config globalconfig=$(get_data_file systempony.conf) if [ -r "$globalconfig" ] then source "$globalconfig" fi # Read user config if [ -r ~/.systempony ] then source ~/.systempony fi # Read parameters while [ "$1" ] do case "$1" in --help|-h|help) help exit 0 ;; --list|--list-ponies) list_ponies exit 0 ;; --pony|-p) shift PONY="$1" ;; -p=*|--pony=*) PONY="$(echo "$1" | sed -r "s/^(-p|--pony)=//")" ;; --info|-i) infostring="" while [ "$2" ] && ! echo "$2" | grep -q -e "-" do infostring="$infostring $2" shift done select_info "$infostring" ;; -i=*|--info=*) select_info "$(echo "$1" | sed -r "s/^(-i|--info)=//")" ;; esac shift done # Evaluate info info_values=() let info_key_max_length=0 let info_val_max_length=0 function addinfo() { info_values+=("${2}") local key_length=$(echo "$1" | wc -c) local val_length=$(echo "${2}" | wc -c) [ $key_length -gt $info_key_max_length ] && info_key_max_length=$key_length; [ $val_length -gt $info_val_max_length ] && info_val_max_length=$val_length; } for info in ${INFO[*]} do if [ "$(type -t ponyget_${info})" = "function" ] then addinfo $info "$(ponyget_${info})" else addinfo $info "unsupported" fi done if [ -f "$PONY" ] then ponyfile="$PONY" elif [ "$PONY" = nopony ] then ponyfile=/dev/null else ponydir=$(get_data_file "rendered/ansi/") ponyfile="$ponydir/$PONY.ansi" if [ -n "$ponydir" -a '(' \! -f "$ponyfile" -o "$PONY" = random ')' ] then ponyfile="$(find "$ponydir" -name '*.ansi' | shuf | head -n 1)" fi fi declare -A info_firstx # Number of characters before the system info output info_firstx[applejack-nohat]=64 info_firstx[applejack]=70 info_firstx[bigmac]=42 info_firstx[celestia]=76 info_firstx[cadance]=55 info_firstx[derpy]=61 info_firstx[fluttershy]=67 info_firstx[great-and-powerful]=68 info_firstx[luna]=67 info_firstx[lyra]=61 info_firstx[pinkie-pie]=61 info_firstx[rainbow-dash]=61 info_firstx[rainbow]=61 info_firstx[rarity]=61 info_firstx[rose]=61 info_firstx[trixie]=61 info_firstx[twilight-alicorn]=61 info_firstx[twilight-unicorn]=61 info_firstx[vinyl-scratch-glasses]=69 info_firstx[vinyl-scratch-noglasses]=69 declare -A info_firsty # Number of lines before the system info output info_firsty[luna]=18 info_firsty[rarity]=11 info_firsty[trixie]=16 info_firsty[twilight-unicorn]=10 info_firsty[twilight-alicorn]=10 if [ -f "$ponyfile" ] then lines=$(cat "$ponyfile" | wc -l) # cat to avoid printing file name let info_index=0 COLUMNS=$(tput cols || echo 1024) if [ "${info_firstx[$PONY]}" ] then info_x=${info_firstx[$PONY]} else info_x=80 fi if [ "${info_firsty[$PONY]}" ] then start_line=${info_firsty[$PONY]} else let start_line=($lines-${#INFO[@]})/2 fi let current_line=1 while IFS= read -r line do if [ $info_index -lt ${#INFO[@]} -a $current_line -ge $start_line ] then let msgsize="$COLUMNS - $info_x - $info_key_max_length - 4" line="$(truncate_color "$line" $info_x)" printf "%s \x1b[31;1m%-${info_key_max_length}s\x1b[0m: %s %s\n" \ "$line$backspaces" \ "${INFO[$info_index]}" \ "$(truncate_color "${info_values[$info_index]}" $msgsize)" let info_index++ else echo -n "$line" echo -e "\x1b[0m" fi let current_line++ done < "$ponyfile" else let info_index=0 while [ $info_index -lt ${#INFO[@]} ] do printf "\x1b[31;1m%-${info_key_max_length}s\x1b[0m: %s\n" \ "${INFO[$info_index]}" \ "${info_values[$info_index]}" let info_index++ done fi