#!/usr/bin/env bash # ------------------------------------------------------------------------------ # Copyright (c) 2013-2026 Geoffray Levasseur # Protected by the BSD3 license. Please read bellow for details. # # * Redistribution and use in source and binary forms, # * with or without modification, are permitted provided # * that the following conditions are met: # * # * Redistributions of source code must retain the above # * copyright notice, this list of conditions and the # * following disclaimer. # * # * Redistributions in binary form must reproduce the above # * copyright notice, this list of conditions and the following # * disclaimer in the documentation and/or other materials # * provided with the distribution. # * # * Neither the name of the copyright holder nor the names # * of any other contributors may be used to endorse or # * promote products derived from this software without # * specific prior written permission. # * # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR # * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # * OF SUCH DAMAGE. # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Show profile version # Usage: ver ver() { local PARSED PARSED=$(getopt -o h --long help -n 'ver' -- "$@") # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"ver --help\" to display usage." return 1 fi eval set -- "$PARSED" while true; do case "$1" in -h|--help) printf "ver: Display the current profile version.\nUsage: ver\n" return 0 ;; --) shift break ;; *) disp E "Invalid options, use \"ver --help\" to display usage." return 1 ;; esac done [[ -z $PROFVERSION ]] && \ disp W "No version defined. Profile is probably badly installed." && \ return 1 disp "Profile version $PROFVERSION." } export -f ver # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Display weather for the given city (or the default one) # Usage: meteo [city1 city2 ...] meteo() { local PARSED PARSED=$(getopt -o h --long help -n 'meteo' -- "$@") # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"meteo --help\" to display usage." return 1 fi eval set -- "$PARSED" while true; do case "$1" in -h|--help) printf "meteo: Fetch weather data.\n" printf "Usage: meteo [city1 city2 ...]\n" printf "If no city is provided, the default city from configuration will be used.\n" return 0 ;; --) shift break ;; *) disp E "Invalid options, use \"meteo --help\" to display usage." return 1 ;; esac done local cities=("$@") local city="" encoded="" [[ $# -eq 0 ]] && cities=("${METEO_DEFAULT_CITY:-}") if [[ ${#cities[@]} -eq 0 || -z "${cities[0]}" ]]; then disp E "No city given and METEO_DEFAULT_CITY is not set. Use 'meteo '." return 1 fi for city in "${cities[@]}"; do encoded=$(urlencode "$city") dwl "https://wttr.in/$encoded" || \ disp E "Failed to fetch weather data for $city." done } export -f meteo # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Display a system information block using only /proc and /sys — no external tools. # Usage: pinfo pinfo() { local _row _row() { printf " %b%-12s%b %b%s%b\n" "$_lbl" "$1" "$_rst" "$_val" "$2" "$_rst" } local PARSED PARSED=$(getopt -o h --long help -n 'pinfo' -- "$@") # shellcheck disable=SC2181 if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"pinfo --help\" to display usage." return 1 fi eval set -- "$PARSED" while true; do case "$1" in -h|--help) printf "pinfo: Display system information from /proc and /sys (no external tools required).\n" printf "Usage: pinfo\n" return 0 ;; --) shift break ;; *) disp E "Invalid options, use \"pinfo --help\" to display usage." return 1 ;; esac done # --- Hostname --- local hostname_str if [[ -r /proc/sys/kernel/hostname ]]; then read -r hostname_str < /proc/sys/kernel/hostname else hostname_str="${HOSTNAME:-unknown}" fi # --- OS release (parsed line by line, never sourced) --- local os_name="Unknown" os_version="" if [[ -r /etc/os-release ]]; then local _osr_key _osr_val while IFS='=' read -r _osr_key _osr_val; do _osr_val="${_osr_val//\"/}" case "$_osr_key" in NAME) os_name="$_osr_val" ;; VERSION_ID) os_version="$_osr_val" ;; esac done < /etc/os-release fi # --- Kernel release --- local kernel_str="unknown" [[ -r /proc/sys/kernel/osrelease ]] && read -r kernel_str < /proc/sys/kernel/osrelease # --- Architecture (set by bash at startup from the ELF interpreter) --- local arch_str="${HOSTTYPE:-unknown}" # --- Uptime (seconds from /proc/uptime) --- local uptime_str="unknown" if [[ -r /proc/uptime ]]; then local _upraw read -r _upraw _ < /proc/uptime local _upsec="${_upraw%%.*}" local _days=$(( _upsec / 86400 )) local _hours=$(( (_upsec % 86400) / 3600 )) local _mins=$(( (_upsec % 3600) / 60 )) local _secs=$(( _upsec % 60 )) uptime_str="" (( _days > 0 )) && uptime_str+="${_days}d " (( _hours > 0 || _days > 0 )) && uptime_str+="${_hours}h " uptime_str+="${_mins}m ${_secs}s" fi # --- Load average --- local load_str="unknown" if [[ -r /proc/loadavg ]]; then local _l1 _l5 _l15 read -r _l1 _l5 _l15 _ < /proc/loadavg load_str="${_l1} ${_l5} ${_l15} (1/5/15 min)" fi # --- CPU model and logical/physical core count (pure bash) --- local cpu_model="unknown" cpu_threads=0 local -A _seen_cores=() local _cur_phys="" _cpu_line if [[ -r /proc/cpuinfo ]]; then while IFS= read -r _cpu_line; do case "$_cpu_line" in "model name"*|"Model name"*|"Hardware"*) [[ "$cpu_model" == "unknown" ]] && cpu_model="${_cpu_line#*: }" ;; "processor"*) (( cpu_threads++ )) ;; "physical id"*) _cur_phys="${_cpu_line#*: }" ;; "core id"*) _seen_cores["${_cur_phys}:${_cpu_line#*: }"]=1 ;; esac done < /proc/cpuinfo fi local cpu_cores="${#_seen_cores[@]}" (( cpu_cores == 0 )) && cpu_cores=$cpu_threads # --- Memory (pure bash, /proc/meminfo, values in kB) --- local mem_total=0 mem_available=0 if [[ -r /proc/meminfo ]]; then local _mkey _mval _munit while read -r _mkey _mval _munit; do case "${_mkey%:}" in MemTotal) mem_total="$_mval" ;; MemAvailable) mem_available="$_mval" ;; esac done < /proc/meminfo fi local mem_total_mib=$(( mem_total / 1024 )) local mem_used_mib=$(( (mem_total - mem_available) / 1024 )) # --- Process count (glob over numeric /proc entries) --- local proc_count=0 _pdir for _pdir in /proc/[0-9]*/; do [[ -d "$_pdir" ]] && (( proc_count++ )) done # --- Shell and terminal --- local shell_str="${BASH:-bash} ${BASH_VERSION%\(*}" local term_str="${TERM:-unknown}" # --- Render --- local _lbl="${BIWhite:-}" _val="${ICyan:-}" _rst="${DEFAULTCOL:-}" printf "\n" _row "Hostname" "$hostname_str" _row "OS" "${os_name}${os_version:+ $os_version}" _row "Kernel" "$kernel_str" _row "Arch" "$arch_str" _row "Uptime" "$uptime_str" _row "Load avg" "$load_str" _row "CPU" "$cpu_model" _row "Cores" "${cpu_cores} physical, ${cpu_threads} logical" _row "Memory" "${mem_used_mib} MiB used / ${mem_total_mib} MiB total" _row "Processes" "$proc_count" _row "Shell" "$shell_str" _row "Terminal" "$term_str" printf "\n" } export -f pinfo # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # Display system general information # Usage: showinfo showinfo() { local PARSED PARSED=$(getopt -o h --long help -n 'showinfo' -- "$@") # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"showinfo --help\" to display usage." return 1 fi eval set -- "$PARSED" while true; do case "$1" in -h|--help) printf "showinfo: Display system information (hostname, kernel, uptime and fetch output when available).\n" printf "Usage: showinfo\n" return 0 ;; --) shift break ;; *) disp E "Invalid options, use \"showinfo --help\" to display usage." return 1 ;; esac done local hostname_str local figopt=() hostname_str="$(hostname)" printf "\n" if command -v figlet >/dev/null 2>&1; then [[ -s /usr/share/figlet/ansi_shadow.flf ]] && \ figopt=(-f ansi_shadow) figlet -k "${figopt[@]}" "$hostname_str" else printf "%s\n" "$hostname_str" fi printf "\n" if command -v neofetch >/dev/null 2>&1; then neofetch elif command -v fastfetch >/dev/null 2>&1; then fastfetch else pinfo "$@" fi } export -f showinfo # ------------------------------------------------------------------------------ load_conf info # EOF