1831 lines
55 KiB
Plaintext
1831 lines
55 KiB
Plaintext
|
#!/bin/sh
|
|||
|
#
|
|||
|
# pfetch - Simple POSIX sh fetch script.
|
|||
|
|
|||
|
# Wrapper around all escape sequences used by pfetch to allow for
|
|||
|
# greater control over which sequences are used (if any at all).
|
|||
|
esc() {
|
|||
|
case $1 in
|
|||
|
CUU) e="${esc_c}[${2}A" ;; # cursor up
|
|||
|
CUD) e="${esc_c}[${2}B" ;; # cursor down
|
|||
|
CUF) e="${esc_c}[${2}C" ;; # cursor right
|
|||
|
CUB) e="${esc_c}[${2}D" ;; # cursor left
|
|||
|
|
|||
|
# text formatting
|
|||
|
SGR)
|
|||
|
case ${PF_COLOR:=1} in
|
|||
|
(1)
|
|||
|
e="${esc_c}[${2}m"
|
|||
|
;;
|
|||
|
|
|||
|
(0)
|
|||
|
# colors disabled
|
|||
|
e=
|
|||
|
;;
|
|||
|
esac
|
|||
|
;;
|
|||
|
|
|||
|
# line wrap
|
|||
|
DECAWM)
|
|||
|
case $TERM in
|
|||
|
(dumb | minix | cons25)
|
|||
|
# not supported
|
|||
|
e=
|
|||
|
;;
|
|||
|
|
|||
|
(*)
|
|||
|
e="${esc_c}[?7${2}"
|
|||
|
;;
|
|||
|
esac
|
|||
|
;;
|
|||
|
esac
|
|||
|
}
|
|||
|
|
|||
|
# Print a sequence to the terminal.
|
|||
|
esc_p() {
|
|||
|
esc "$@"
|
|||
|
printf '%s' "$e"
|
|||
|
}
|
|||
|
|
|||
|
# This is just a simple wrapper around 'command -v' to avoid
|
|||
|
# spamming '>/dev/null' throughout this function. This also guards
|
|||
|
# against aliases and functions.
|
|||
|
has() {
|
|||
|
_cmd=$(command -v "$1") 2>/dev/null || return 1
|
|||
|
[ -x "$_cmd" ] || return 1
|
|||
|
}
|
|||
|
|
|||
|
log() {
|
|||
|
# The 'log()' function handles the printing of information.
|
|||
|
# In 'pfetch' (and 'neofetch'!) the printing of the ascii art and info
|
|||
|
# happen independently of each other.
|
|||
|
#
|
|||
|
# The size of the ascii art is stored and the ascii is printed first.
|
|||
|
# Once the ascii is printed, the cursor is located right below the art
|
|||
|
# (See marker $[1]).
|
|||
|
#
|
|||
|
# Using the stored ascii size, the cursor is then moved to marker $[2].
|
|||
|
# This is simply a cursor up escape sequence using the "height" of the
|
|||
|
# ascii art.
|
|||
|
#
|
|||
|
# 'log()' then moves the cursor to the right the "width" of the ascii art
|
|||
|
# with an additional amount of padding to add a gap between the art and
|
|||
|
# the information (See marker $[3]).
|
|||
|
#
|
|||
|
# When 'log()' has executed, the cursor is then located at marker $[4].
|
|||
|
# When 'log()' is run a second time, the next line of information is
|
|||
|
# printed, moving the cursor to marker $[5].
|
|||
|
#
|
|||
|
# Markers $[4] and $[5] repeat all the way down through the ascii art
|
|||
|
# until there is no more information left to print.
|
|||
|
#
|
|||
|
# Every time 'log()' is called the script keeps track of how many lines
|
|||
|
# were printed. When printing is complete the cursor is then manually
|
|||
|
# placed below the information and the art according to the "heights"
|
|||
|
# of both.
|
|||
|
#
|
|||
|
# The math is simple: move cursor down $((ascii_height - info_height)).
|
|||
|
# If the aim is to move the cursor from marker $[5] to marker $[6],
|
|||
|
# plus the ascii height is 8 while the info height is 2 it'd be a move
|
|||
|
# of 6 lines downwards.
|
|||
|
#
|
|||
|
# However, if the information printed is "taller" (takes up more lines)
|
|||
|
# than the ascii art, the cursor isn't moved at all!
|
|||
|
#
|
|||
|
# Once the cursor is at marker $[6], the script exits. This is the gist
|
|||
|
# of how this "dynamic" printing and layout works.
|
|||
|
#
|
|||
|
# This method allows ascii art to be stored without markers for info
|
|||
|
# and it allows for easy swapping of info order and amount.
|
|||
|
#
|
|||
|
# $[2] ___ $[3] goldie@KISS
|
|||
|
# $[4](.· | $[5] os KISS Linux
|
|||
|
# (<> |
|
|||
|
# / __ \
|
|||
|
# ( / \ /|
|
|||
|
# _/\ __)/_)
|
|||
|
# \/-____\/
|
|||
|
# $[1]
|
|||
|
#
|
|||
|
# $[6] /home/goldie $
|
|||
|
|
|||
|
# End here if no data was found.
|
|||
|
[ "$2" ] || return
|
|||
|
|
|||
|
# Store the value of '$1' as we reset the argument list below.
|
|||
|
name=$1
|
|||
|
|
|||
|
# Use 'set --' as a means of stripping all leading and trailing
|
|||
|
# white-space from the info string. This also normalizes all
|
|||
|
# white-space inside of the string.
|
|||
|
#
|
|||
|
# Disable the shellcheck warning for word-splitting
|
|||
|
# as it's safe and intended ('set -f' disables globbing).
|
|||
|
# shellcheck disable=2046,2086
|
|||
|
{
|
|||
|
set -f
|
|||
|
set +f -- $2
|
|||
|
info=$*
|
|||
|
}
|
|||
|
|
|||
|
# Move the cursor to the right, the width of the ascii art with an
|
|||
|
# additional gap for text spacing.
|
|||
|
esc_p CUF "$ascii_width"
|
|||
|
|
|||
|
# Print the info name and color the text.
|
|||
|
esc_p SGR "3${PF_COL1-4}";
|
|||
|
esc_p SGR 1
|
|||
|
printf '%s' "$name"
|
|||
|
esc_p SGR 0
|
|||
|
|
|||
|
# Print the info name and info data separator.
|
|||
|
printf %s "$PF_SEP"
|
|||
|
|
|||
|
# Move the cursor backward the length of the *current* info name and
|
|||
|
# then move it forwards the length of the *longest* info name. This
|
|||
|
# aligns each info data line.
|
|||
|
esc_p CUB "${#name}"
|
|||
|
esc_p CUF "${PF_ALIGN:-$info_length}"
|
|||
|
|
|||
|
# Print the info data, color it and strip all leading whitespace
|
|||
|
# from the string.
|
|||
|
esc_p SGR "3${PF_COL2-7}"
|
|||
|
printf '%s' "$info"
|
|||
|
esc_p SGR 0
|
|||
|
printf '\n'
|
|||
|
|
|||
|
# Keep track of the number of times 'log()' has been run.
|
|||
|
info_height=$((${info_height:-0} + 1))
|
|||
|
}
|
|||
|
|
|||
|
get_title() {
|
|||
|
# Username is retrieved by first checking '$USER' with a fallback
|
|||
|
# to the 'id -un' command.
|
|||
|
user=${USER:-$(id -un)}
|
|||
|
|
|||
|
# Hostname is retrieved by first checking '$HOSTNAME' with a fallback
|
|||
|
# to the 'hostname' command.
|
|||
|
#
|
|||
|
# Disable the warning about '$HOSTNAME' being undefined in POSIX sh as
|
|||
|
# the intention for using it is allowing the user to overwrite the
|
|||
|
# value on invocation.
|
|||
|
# shellcheck disable=SC3028
|
|||
|
host=${HOSTNAME:-${host:-$(hostname)}}
|
|||
|
|
|||
|
# If the hostname is still not found, fallback to the contents of the
|
|||
|
# /etc/hostname file.
|
|||
|
[ "$host" ] || read -r host < /etc/hostname
|
|||
|
|
|||
|
# Add escape sequences for coloring to user and host name. As we embed
|
|||
|
# them directly in the arguments passed to log(), we cannot use esc_p().
|
|||
|
esc SGR 1
|
|||
|
user=$e$user
|
|||
|
esc SGR "3${PF_COL3:-1}"
|
|||
|
user=$e$user
|
|||
|
esc SGR 1
|
|||
|
user=$user$e
|
|||
|
esc SGR 1
|
|||
|
host=$e$host
|
|||
|
esc SGR "3${PF_COL3:-1}"
|
|||
|
host=$e$host
|
|||
|
|
|||
|
log "${user}@${host}" " " >&6
|
|||
|
}
|
|||
|
|
|||
|
get_os() {
|
|||
|
# This function is called twice, once to detect the distribution name
|
|||
|
# for the purposes of picking an ascii art early and secondly to display
|
|||
|
# the distribution name in the info output (if enabled).
|
|||
|
#
|
|||
|
# On first run, this function displays _nothing_, only on the second
|
|||
|
# invocation is 'log()' called.
|
|||
|
[ "$distro" ] && {
|
|||
|
log os "$distro" >&6
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
case $os in
|
|||
|
(Linux*)
|
|||
|
# Some Linux distributions (which are based on others)
|
|||
|
# fail to identify as they **do not** change the upstream
|
|||
|
# distribution's identification packages or files.
|
|||
|
#
|
|||
|
# It is senseless to add a special case in the code for
|
|||
|
# each and every distribution (which _is_ technically no
|
|||
|
# different from what it is based on) as they're either too
|
|||
|
# lazy to modify upstream's identification files or they
|
|||
|
# don't have the know-how (or means) to ship their own
|
|||
|
# lsb-release package.
|
|||
|
#
|
|||
|
# This causes users to think there's a bug in system detection
|
|||
|
# tools like neofetch or pfetch when they technically *do*
|
|||
|
# function correctly.
|
|||
|
#
|
|||
|
# Exceptions are made for distributions which are independent,
|
|||
|
# not based on another distribution or follow different
|
|||
|
# standards.
|
|||
|
#
|
|||
|
# This applies only to distributions which follow the standard
|
|||
|
# by shipping unmodified identification files and packages
|
|||
|
# from their respective upstreams.
|
|||
|
if has lsb_release; then
|
|||
|
distro=$(lsb_release -sd)
|
|||
|
|
|||
|
# Android detection works by checking for the existence of
|
|||
|
# the follow two directories. I don't think there's a simpler
|
|||
|
# method than this.
|
|||
|
elif [ -d /system/app ] && [ -d /system/priv-app ]; then
|
|||
|
distro="Android $(getprop ro.build.version.release)"
|
|||
|
|
|||
|
else
|
|||
|
# This used to be a simple '. /etc/os-release' but I believe
|
|||
|
# this is insecure as we blindly executed whatever was in the
|
|||
|
# file. This parser instead simply handles 'key=val', treating
|
|||
|
# the file contents as plain-text.
|
|||
|
while IFS='=' read -r key val; do
|
|||
|
case $key in
|
|||
|
(PRETTY_NAME)
|
|||
|
distro=$val
|
|||
|
;;
|
|||
|
esac
|
|||
|
done < /etc/os-release
|
|||
|
fi
|
|||
|
|
|||
|
# 'os-release' and 'lsb_release' sometimes add quotes
|
|||
|
# around the distribution name, strip them.
|
|||
|
distro=${distro##[\"\']}
|
|||
|
distro=${distro%%[\"\']}
|
|||
|
|
|||
|
# Special cases for (independent) distributions which
|
|||
|
# don't follow any os-release/lsb standards whatsoever.
|
|||
|
has crux && distro=$(crux)
|
|||
|
has guix && distro='Guix System'
|
|||
|
|
|||
|
# Check to see if we're running Bedrock Linux which is
|
|||
|
# very unique. This simply checks to see if the user's
|
|||
|
# PATH contains a Bedrock specific value.
|
|||
|
case $PATH in
|
|||
|
(*/bedrock/cross/*)
|
|||
|
distro='Bedrock Linux'
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
# Check to see if Linux is running in Windows 10 under
|
|||
|
# WSL1 (Windows subsystem for Linux [version 1]) and
|
|||
|
# append a string accordingly.
|
|||
|
#
|
|||
|
# If the kernel version string ends in "-Microsoft",
|
|||
|
# we're very likely running under Windows 10 in WSL1.
|
|||
|
if [ "$WSLENV" ]; then
|
|||
|
distro="${distro}${WSLENV+ on Windows 10 [WSL2]}"
|
|||
|
|
|||
|
# Check to see if Linux is running in Windows 10 under
|
|||
|
# WSL2 (Windows subsystem for Linux [version 2]) and
|
|||
|
# append a string accordingly.
|
|||
|
#
|
|||
|
# This checks to see if '$WSLENV' is defined. This
|
|||
|
# appends the Windows 10 string even if '$WSLENV' is
|
|||
|
# empty. We only need to check that is has been _exported_.
|
|||
|
elif [ -z "${kernel%%*-Microsoft}" ]; then
|
|||
|
distro="$distro on Windows 10 [WSL1]"
|
|||
|
fi
|
|||
|
;;
|
|||
|
|
|||
|
(Darwin*)
|
|||
|
# Parse the SystemVersion.plist file to grab the macOS
|
|||
|
# version. The file is in the following format:
|
|||
|
#
|
|||
|
# <key>ProductVersion</key>
|
|||
|
# <string>10.14.6</string>
|
|||
|
#
|
|||
|
# 'IFS' is set to '<>' to enable splitting between the
|
|||
|
# keys and a second 'read' is used to operate on the
|
|||
|
# next line directly after a match.
|
|||
|
#
|
|||
|
# '_' is used to nullify a field. '_ _ line _' basically
|
|||
|
# says "populate $line with the third field's contents".
|
|||
|
while IFS='<>' read -r _ _ line _; do
|
|||
|
case $line in
|
|||
|
# Match 'ProductVersion' and read the next line
|
|||
|
# directly as it contains the key's value.
|
|||
|
ProductVersion)
|
|||
|
IFS='<>' read -r _ _ mac_version _
|
|||
|
continue
|
|||
|
;;
|
|||
|
|
|||
|
ProductName)
|
|||
|
IFS='<>' read -r _ _ mac_product _
|
|||
|
continue
|
|||
|
;;
|
|||
|
esac
|
|||
|
done < /System/Library/CoreServices/SystemVersion.plist
|
|||
|
|
|||
|
# Use the ProductVersion to determine which macOS/OS X codename
|
|||
|
# the system has. As far as I'm aware there's no "dynamic" way
|
|||
|
# of grabbing this information.
|
|||
|
case $mac_version in
|
|||
|
(10.4*) distro='Mac OS X Tiger' ;;
|
|||
|
(10.5*) distro='Mac OS X Leopard' ;;
|
|||
|
(10.6*) distro='Mac OS X Snow Leopard' ;;
|
|||
|
(10.7*) distro='Mac OS X Lion' ;;
|
|||
|
(10.8*) distro='OS X Mountain Lion' ;;
|
|||
|
(10.9*) distro='OS X Mavericks' ;;
|
|||
|
(10.10*) distro='OS X Yosemite' ;;
|
|||
|
(10.11*) distro='OS X El Capitan' ;;
|
|||
|
(10.12*) distro='macOS Sierra' ;;
|
|||
|
(10.13*) distro='macOS High Sierra' ;;
|
|||
|
(10.14*) distro='macOS Mojave' ;;
|
|||
|
(10.15*) distro='macOS Catalina' ;;
|
|||
|
(11*) distro='macOS Big Sur' ;;
|
|||
|
(*) distro='macOS' ;;
|
|||
|
esac
|
|||
|
|
|||
|
# Use the ProductName to determine if we're running in iOS.
|
|||
|
case $mac_product in
|
|||
|
(iP*) distro='iOS' ;;
|
|||
|
esac
|
|||
|
|
|||
|
distro="$distro $mac_version"
|
|||
|
;;
|
|||
|
|
|||
|
(Haiku)
|
|||
|
# Haiku uses 'uname -v' for version information
|
|||
|
# instead of 'uname -r' which only prints '1'.
|
|||
|
distro=$(uname -sv)
|
|||
|
;;
|
|||
|
|
|||
|
(Minix|DragonFly)
|
|||
|
distro="$os $kernel"
|
|||
|
|
|||
|
# Minix and DragonFly don't support the escape
|
|||
|
# sequences used, clear the exit trap.
|
|||
|
trap '' EXIT
|
|||
|
;;
|
|||
|
|
|||
|
(SunOS)
|
|||
|
# Grab the first line of the '/etc/release' file
|
|||
|
# discarding everything after '('.
|
|||
|
IFS='(' read -r distro _ < /etc/release
|
|||
|
;;
|
|||
|
|
|||
|
(OpenBSD*)
|
|||
|
# Show the OpenBSD version type (current if present).
|
|||
|
# kern.version=OpenBSD 6.6-current (GENERIC.MP) ...
|
|||
|
IFS=' =' read -r _ distro openbsd_ver _ <<-EOF
|
|||
|
$(sysctl kern.version)
|
|||
|
EOF
|
|||
|
|
|||
|
distro="$distro $openbsd_ver"
|
|||
|
;;
|
|||
|
|
|||
|
FreeBSD)
|
|||
|
distro="$os $(freebsd-version)"
|
|||
|
;;
|
|||
|
|
|||
|
(*)
|
|||
|
# Catch all to ensure '$distro' is never blank.
|
|||
|
# This also handles the BSDs.
|
|||
|
distro="$os $kernel"
|
|||
|
;;
|
|||
|
esac
|
|||
|
}
|
|||
|
|
|||
|
get_kernel() {
|
|||
|
case $os in
|
|||
|
# Don't print kernel output on some systems as the
|
|||
|
# OS name includes it.
|
|||
|
(*BSD*|Haiku|Minix)
|
|||
|
return
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
# '$kernel' is the cached output of 'uname -r'.
|
|||
|
log kernel "$kernel" >&6
|
|||
|
}
|
|||
|
|
|||
|
get_host() {
|
|||
|
case $os in
|
|||
|
(Linux*)
|
|||
|
# Despite what these files are called, version doesn't
|
|||
|
# always contain the version nor does name always contain
|
|||
|
# the name.
|
|||
|
read -r name < /sys/devices/virtual/dmi/id/product_name
|
|||
|
read -r version < /sys/devices/virtual/dmi/id/product_version
|
|||
|
read -r model < /sys/firmware/devicetree/base/model
|
|||
|
|
|||
|
host="$name $version $model"
|
|||
|
;;
|
|||
|
|
|||
|
(Darwin* | FreeBSD* | DragonFly*)
|
|||
|
host=$(sysctl -n hw.model)
|
|||
|
;;
|
|||
|
|
|||
|
(NetBSD*)
|
|||
|
host=$(sysctl -n machdep.dmi.system-vendor \
|
|||
|
machdep.dmi.system-product)
|
|||
|
;;
|
|||
|
|
|||
|
(OpenBSD*)
|
|||
|
host=$(sysctl -n hw.version)
|
|||
|
;;
|
|||
|
|
|||
|
(*BSD* | Minix)
|
|||
|
host=$(sysctl -n hw.vendor hw.product)
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
# Turn the host string into an argument list so we can iterate
|
|||
|
# over it and remove OEM strings and other information which
|
|||
|
# shouldn't be displayed.
|
|||
|
#
|
|||
|
# Disable the shellcheck warning for word-splitting
|
|||
|
# as it's safe and intended ('set -f' disables globbing).
|
|||
|
# shellcheck disable=2046,2086
|
|||
|
{
|
|||
|
set -f
|
|||
|
set +f -- $host
|
|||
|
host=
|
|||
|
}
|
|||
|
|
|||
|
# Iterate over the host string word by word as a means of stripping
|
|||
|
# unwanted and OEM information from the string as a whole.
|
|||
|
#
|
|||
|
# This could have been implemented using a long 'sed' command with
|
|||
|
# a list of word replacements, however I want to show that something
|
|||
|
# like this is possible in pure sh.
|
|||
|
#
|
|||
|
# This string reconstruction is needed as some OEMs either leave the
|
|||
|
# identification information as "To be filled by OEM", "Default",
|
|||
|
# "undefined" etc and we shouldn't print this to the screen.
|
|||
|
for word do
|
|||
|
# This works by reconstructing the string by excluding words
|
|||
|
# found in the "blacklist" below. Only non-matches are appended
|
|||
|
# to the final host string.
|
|||
|
case $word in
|
|||
|
(To | [Bb]e | [Ff]illed | [Bb]y | O.E.M. | OEM |\
|
|||
|
Not | Applicable | Specified | System | Product | Name |\
|
|||
|
Version | Undefined | Default | string | INVALID | <20> | os |\
|
|||
|
Type1ProductConfigId )
|
|||
|
continue
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
host="$host$word "
|
|||
|
done
|
|||
|
|
|||
|
# '$arch' is the cached output from 'uname -m'.
|
|||
|
log host "${host:-$arch}" >&6
|
|||
|
}
|
|||
|
|
|||
|
get_uptime() {
|
|||
|
# Uptime works by retrieving the data in total seconds and then
|
|||
|
# converting that data into days, hours and minutes using simple
|
|||
|
# math.
|
|||
|
case $os in
|
|||
|
(Linux* | Minix*)
|
|||
|
IFS=. read -r s _ < /proc/uptime
|
|||
|
;;
|
|||
|
|
|||
|
Darwin* | *BSD* | DragonFly*)
|
|||
|
s=$(sysctl -n kern.boottime)
|
|||
|
|
|||
|
# Extract the uptime in seconds from the following output:
|
|||
|
# [...] { sec = 1271934886, usec = 667779 } Thu Apr 22 12:14:46 2010
|
|||
|
s=${s#*=}
|
|||
|
s=${s%,*}
|
|||
|
|
|||
|
# The uptime format from 'sysctl' needs to be subtracted from
|
|||
|
# the current time in seconds.
|
|||
|
s=$(($(date +%s) - s))
|
|||
|
;;
|
|||
|
|
|||
|
(Haiku)
|
|||
|
# The boot time is returned in microseconds, convert it to
|
|||
|
# regular seconds.
|
|||
|
s=$(($(system_time) / 1000000))
|
|||
|
;;
|
|||
|
|
|||
|
(SunOS)
|
|||
|
# Split the output of 'kstat' on '.' and any white-space
|
|||
|
# which exists in the command output.
|
|||
|
#
|
|||
|
# The output is as follows:
|
|||
|
# unix:0:system_misc:snaptime 14809.906993005
|
|||
|
#
|
|||
|
# The parser extracts: ^^^^^
|
|||
|
IFS=' .' read -r _ s _ <<-EOF
|
|||
|
$(kstat -p unix:0:system_misc:snaptime)
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
(IRIX)
|
|||
|
# Grab the uptime in a pretty format. Usually,
|
|||
|
# 00:00:00 from the 'ps' command.
|
|||
|
t=$(LC_ALL=POSIX ps -o etime= -p 1)
|
|||
|
|
|||
|
# Split the pretty output into days or hours
|
|||
|
# based on the uptime.
|
|||
|
case $t in
|
|||
|
(*-*) d=${t%%-*} t=${t#*-} ;;
|
|||
|
(*:*:*) h=${t%%:*} t=${t#*:} ;;
|
|||
|
esac
|
|||
|
|
|||
|
h=${h#0} t=${t#0}
|
|||
|
|
|||
|
# Convert the split pretty fields back into
|
|||
|
# seconds so we may re-convert them to our format.
|
|||
|
s=$((${d:-0}*86400 + ${h:-0}*3600 + ${t%%:*}*60 + ${t#*:}))
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
# Convert the uptime from seconds into days, hours and minutes.
|
|||
|
d=$((s / 60 / 60 / 24))
|
|||
|
h=$((s / 60 / 60 % 24))
|
|||
|
m=$((s / 60 % 60))
|
|||
|
|
|||
|
# Only append days, hours and minutes if they're non-zero.
|
|||
|
case "$d" in ([!0]*) uptime="${uptime}${d}d "; esac
|
|||
|
case "$h" in ([!0]*) uptime="${uptime}${h}h "; esac
|
|||
|
case "$m" in ([!0]*) uptime="${uptime}${m}m "; esac
|
|||
|
|
|||
|
log uptime "${uptime:-0m}" >&6
|
|||
|
}
|
|||
|
|
|||
|
get_pkgs() {
|
|||
|
# This works by first checking for which package managers are
|
|||
|
# installed and finally by printing each package manager's
|
|||
|
# package list with each package one per line.
|
|||
|
#
|
|||
|
# The output from this is then piped to 'wc -l' to count each
|
|||
|
# line, giving us the total package count of whatever package
|
|||
|
# managers are installed.
|
|||
|
#
|
|||
|
# Backticks are *required* here as '/bin/sh' on macOS is
|
|||
|
# 'bash 3.2' and it can't handle the following:
|
|||
|
#
|
|||
|
# var=$(
|
|||
|
# code here
|
|||
|
# )
|
|||
|
#
|
|||
|
# shellcheck disable=2006
|
|||
|
packages=`
|
|||
|
case $os in
|
|||
|
(Linux*)
|
|||
|
# Commands which print packages one per line.
|
|||
|
has bonsai && bonsai list
|
|||
|
has crux && pkginfo -i
|
|||
|
has pacman-key && pacman -Qq
|
|||
|
has dpkg && dpkg-query -f '.\n' -W
|
|||
|
has rpm && rpm -qa
|
|||
|
has xbps-query && xbps-query -l
|
|||
|
has apk && apk info
|
|||
|
has guix && guix package --list-installed
|
|||
|
has opkg && opkg list-installed
|
|||
|
|
|||
|
# Directories containing packages.
|
|||
|
has kiss && printf '%s\n' /var/db/kiss/installed/*/
|
|||
|
has cpt-list && printf '%s\n' /var/db/cpt/installed/*/
|
|||
|
has brew && printf '%s\n' "$(brew --cellar)/"*
|
|||
|
has emerge && printf '%s\n' /var/db/pkg/*/*/
|
|||
|
has pkgtool && printf '%s\n' /var/log/packages/*
|
|||
|
has eopkg && printf '%s\n' /var/lib/eopkg/package/*
|
|||
|
|
|||
|
# 'nix' requires two commands.
|
|||
|
has nix-store && {
|
|||
|
nix-store -q --requisites /run/current-system/sw
|
|||
|
nix-store -q --requisites ~/.nix-profile
|
|||
|
}
|
|||
|
;;
|
|||
|
|
|||
|
(Darwin*)
|
|||
|
# Commands which print packages one per line.
|
|||
|
has pkgin && pkgin list
|
|||
|
has dpkg && dpkg-query -f '.\n' -W
|
|||
|
|
|||
|
# Directories containing packages.
|
|||
|
has brew && printf '%s\n' /usr/local/Cellar/*
|
|||
|
|
|||
|
# 'port' prints a single line of output to 'stdout'
|
|||
|
# when no packages are installed and exits with
|
|||
|
# success causing a false-positive of 1 package
|
|||
|
# installed.
|
|||
|
#
|
|||
|
# 'port' should really exit with a non-zero code
|
|||
|
# in this case to allow scripts to cleanly handle
|
|||
|
# this behavior.
|
|||
|
has port && {
|
|||
|
pkg_list=$(port installed)
|
|||
|
|
|||
|
case "$pkg_list" in
|
|||
|
("No ports are installed.")
|
|||
|
# do nothing
|
|||
|
;;
|
|||
|
|
|||
|
(*)
|
|||
|
printf '%s\n' "$pkg_list"
|
|||
|
;;
|
|||
|
esac
|
|||
|
}
|
|||
|
;;
|
|||
|
|
|||
|
(FreeBSD*|DragonFly*)
|
|||
|
pkg info
|
|||
|
;;
|
|||
|
|
|||
|
(OpenBSD*)
|
|||
|
printf '%s\n' /var/db/pkg/*/
|
|||
|
;;
|
|||
|
|
|||
|
(NetBSD*)
|
|||
|
pkg_info
|
|||
|
;;
|
|||
|
|
|||
|
(Haiku)
|
|||
|
printf '%s\n' /boot/system/package-links/*
|
|||
|
;;
|
|||
|
|
|||
|
(Minix)
|
|||
|
printf '%s\n' /usr/pkg/var/db/pkg/*/
|
|||
|
;;
|
|||
|
|
|||
|
(SunOS)
|
|||
|
has pkginfo && pkginfo -i
|
|||
|
has pkg && pkg list
|
|||
|
;;
|
|||
|
|
|||
|
(IRIX)
|
|||
|
versions -b
|
|||
|
;;
|
|||
|
esac | wc -l
|
|||
|
`
|
|||
|
|
|||
|
case $os in
|
|||
|
# IRIX's package manager adds 3 lines of extra
|
|||
|
# output which we must account for here.
|
|||
|
(IRIX)
|
|||
|
packages=$((packages - 3))
|
|||
|
;;
|
|||
|
|
|||
|
# OpenBSD's wc prints whitespace before the output
|
|||
|
# which needs to be stripped.
|
|||
|
(OpenBSD)
|
|||
|
packages=$((packages))
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
case $packages in
|
|||
|
(1?*|[2-9]*)
|
|||
|
log pkgs "$packages" >&6
|
|||
|
;;
|
|||
|
esac
|
|||
|
}
|
|||
|
|
|||
|
get_memory() {
|
|||
|
case $os in
|
|||
|
# Used memory is calculated using the following "formula":
|
|||
|
# MemUsed = MemTotal + Shmem - MemFree - Buffers - Cached - SReclaimable
|
|||
|
# Source: https://github.com/KittyKatt/screenFetch/issues/386
|
|||
|
(Linux*)
|
|||
|
# Parse the '/proc/meminfo' file splitting on ':' and 'k'.
|
|||
|
# The format of the file is 'key: 000kB' and an additional
|
|||
|
# split is used on 'k' to filter out 'kB'.
|
|||
|
while IFS=':k ' read -r key val _; do
|
|||
|
case $key in
|
|||
|
(MemTotal)
|
|||
|
mem_used=$((mem_used + val))
|
|||
|
mem_full=$val
|
|||
|
;;
|
|||
|
|
|||
|
(Shmem)
|
|||
|
mem_used=$((mem_used + val))
|
|||
|
;;
|
|||
|
|
|||
|
(MemFree | Buffers | Cached | SReclaimable)
|
|||
|
mem_used=$((mem_used - val))
|
|||
|
;;
|
|||
|
|
|||
|
# If detected this will be used over the above calculation
|
|||
|
# for mem_used. Available since Linux 3.14rc.
|
|||
|
# See kernel commit 34e431b0ae398fc54ea69ff85ec700722c9da773
|
|||
|
(MemAvailable)
|
|||
|
mem_avail=$val
|
|||
|
;;
|
|||
|
esac
|
|||
|
done < /proc/meminfo
|
|||
|
|
|||
|
case $mem_avail in
|
|||
|
(*[0-9]*)
|
|||
|
mem_used=$(((mem_full - mem_avail) / 1024))
|
|||
|
;;
|
|||
|
|
|||
|
*)
|
|||
|
mem_used=$((mem_used / 1024))
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
mem_full=$((mem_full / 1024))
|
|||
|
;;
|
|||
|
|
|||
|
# Used memory is calculated using the following "formula":
|
|||
|
# (wired + active + occupied) * 4 / 1024
|
|||
|
(Darwin*)
|
|||
|
mem_full=$(($(sysctl -n hw.memsize) / 1024 / 1024))
|
|||
|
|
|||
|
# Parse the 'vmstat' file splitting on ':' and '.'.
|
|||
|
# The format of the file is 'key: 000.' and an additional
|
|||
|
# split is used on '.' to filter it out.
|
|||
|
while IFS=:. read -r key val; do
|
|||
|
case $key in
|
|||
|
(*' wired'*|*' active'*|*' occupied'*)
|
|||
|
mem_used=$((mem_used + ${val:-0}))
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
# Using '<<-EOF' is the only way to loop over a command's
|
|||
|
# output without the use of a pipe ('|').
|
|||
|
# This ensures that any variables defined in the while loop
|
|||
|
# are still accessible in the script.
|
|||
|
done <<-EOF
|
|||
|
$(vm_stat)
|
|||
|
EOF
|
|||
|
|
|||
|
mem_used=$((mem_used * 4 / 1024))
|
|||
|
;;
|
|||
|
|
|||
|
(OpenBSD*)
|
|||
|
mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024))
|
|||
|
|
|||
|
# This is a really simpler parser for 'vmstat' which grabs
|
|||
|
# the used memory amount in a lazy way. 'vmstat' prints 3
|
|||
|
# lines of output with the needed value being stored in the
|
|||
|
# final line.
|
|||
|
#
|
|||
|
# This loop simply grabs the 3rd element of each line until
|
|||
|
# the EOF is reached. Each line overwrites the value of the
|
|||
|
# previous one so we're left with what we wanted. This isn't
|
|||
|
# slow as only 3 lines are parsed.
|
|||
|
while read -r _ _ line _; do
|
|||
|
mem_used=${line%%M}
|
|||
|
|
|||
|
# Using '<<-EOF' is the only way to loop over a command's
|
|||
|
# output without the use of a pipe ('|').
|
|||
|
# This ensures that any variables defined in the while loop
|
|||
|
# are still accessible in the script.
|
|||
|
done <<-EOF
|
|||
|
$(vmstat)
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
# Used memory is calculated using the following "formula":
|
|||
|
# mem_full - ((inactive + free + cache) * page_size / 1024)
|
|||
|
(FreeBSD*|DragonFly*)
|
|||
|
mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024))
|
|||
|
|
|||
|
# Use 'set --' to store the output of the command in the
|
|||
|
# argument list. POSIX sh has no arrays but this is close enough.
|
|||
|
#
|
|||
|
# Disable the shellcheck warning for word-splitting
|
|||
|
# as it's safe and intended ('set -f' disables globbing).
|
|||
|
# shellcheck disable=2046
|
|||
|
{
|
|||
|
set -f
|
|||
|
set +f -- $(sysctl -n hw.pagesize \
|
|||
|
vm.stats.vm.v_inactive_count \
|
|||
|
vm.stats.vm.v_free_count \
|
|||
|
vm.stats.vm.v_cache_count)
|
|||
|
}
|
|||
|
|
|||
|
# Calculate the amount of used memory.
|
|||
|
# $1: hw.pagesize
|
|||
|
# $2: vm.stats.vm.v_inactive_count
|
|||
|
# $3: vm.stats.vm.v_free_count
|
|||
|
# $4: vm.stats.vm.v_cache_count
|
|||
|
mem_used=$((mem_full - (($2 + $3 + $4) * $1 / 1024 / 1024)))
|
|||
|
;;
|
|||
|
|
|||
|
(NetBSD*)
|
|||
|
mem_full=$(($(sysctl -n hw.physmem64) / 1024 / 1024))
|
|||
|
|
|||
|
# NetBSD implements a lot of the Linux '/proc' filesystem,
|
|||
|
# this uses the same parser as the Linux memory detection.
|
|||
|
while IFS=':k ' read -r key val _; do
|
|||
|
case $key in
|
|||
|
(MemFree)
|
|||
|
mem_free=$((val / 1024))
|
|||
|
break
|
|||
|
;;
|
|||
|
esac
|
|||
|
done < /proc/meminfo
|
|||
|
|
|||
|
mem_used=$((mem_full - mem_free))
|
|||
|
;;
|
|||
|
|
|||
|
(Haiku)
|
|||
|
# Read the first line of 'sysinfo -mem' splitting on
|
|||
|
# '(', ' ', and ')'. The needed information is then
|
|||
|
# stored in the 5th and 7th elements. Using '_' "consumes"
|
|||
|
# an element allowing us to proceed to the next one.
|
|||
|
#
|
|||
|
# The parsed format is as follows:
|
|||
|
# 3501142016 bytes free (used/max 792645632 / 4293787648)
|
|||
|
IFS='( )' read -r _ _ _ _ mem_used _ mem_full <<-EOF
|
|||
|
$(sysinfo -mem)
|
|||
|
EOF
|
|||
|
|
|||
|
mem_used=$((mem_used / 1024 / 1024))
|
|||
|
mem_full=$((mem_full / 1024 / 1024))
|
|||
|
;;
|
|||
|
|
|||
|
(Minix)
|
|||
|
# Minix includes the '/proc' filesystem though the format
|
|||
|
# differs from Linux. The '/proc/meminfo' file is only a
|
|||
|
# single line with space separated elements and elements
|
|||
|
# 2 and 3 contain the total and free memory numbers.
|
|||
|
read -r _ mem_full mem_free _ < /proc/meminfo
|
|||
|
|
|||
|
mem_used=$(((mem_full - mem_free) / 1024))
|
|||
|
mem_full=$(( mem_full / 1024))
|
|||
|
;;
|
|||
|
|
|||
|
(SunOS)
|
|||
|
hw_pagesize=$(pagesize)
|
|||
|
|
|||
|
# 'kstat' outputs memory in the following format:
|
|||
|
# unix:0:system_pages:pagestotal 1046397
|
|||
|
# unix:0:system_pages:pagesfree 885018
|
|||
|
#
|
|||
|
# This simply uses the first "element" (white-space
|
|||
|
# separated) as the key and the second element as the
|
|||
|
# value.
|
|||
|
#
|
|||
|
# A variable is then assigned based on the key.
|
|||
|
while read -r key val; do
|
|||
|
case $key in
|
|||
|
(*total)
|
|||
|
pages_full=$val
|
|||
|
;;
|
|||
|
|
|||
|
(*free)
|
|||
|
pages_free=$val
|
|||
|
;;
|
|||
|
esac
|
|||
|
done <<-EOF
|
|||
|
$(kstat -p unix:0:system_pages:pagestotal \
|
|||
|
unix:0:system_pages:pagesfree)
|
|||
|
EOF
|
|||
|
|
|||
|
mem_full=$((pages_full * hw_pagesize / 1024 / 1024))
|
|||
|
mem_free=$((pages_free * hw_pagesize / 1024 / 1024))
|
|||
|
mem_used=$((mem_full - mem_free))
|
|||
|
;;
|
|||
|
|
|||
|
(IRIX)
|
|||
|
# Read the memory information from the 'top' command. Parse
|
|||
|
# and split each line until we reach the line starting with
|
|||
|
# "Memory".
|
|||
|
#
|
|||
|
# Example output: Memory: 160M max, 147M avail, .....
|
|||
|
while IFS=' :' read -r label mem_full _ mem_free _; do
|
|||
|
case $label in
|
|||
|
(Memory)
|
|||
|
mem_full=${mem_full%M}
|
|||
|
mem_free=${mem_free%M}
|
|||
|
break
|
|||
|
;;
|
|||
|
esac
|
|||
|
done <<-EOF
|
|||
|
$(top -n)
|
|||
|
EOF
|
|||
|
|
|||
|
mem_used=$((mem_full - mem_free))
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
log memory "${mem_used:-?}M / ${mem_full:-?}M" >&6
|
|||
|
}
|
|||
|
|
|||
|
get_wm() {
|
|||
|
case $os in
|
|||
|
(Darwin*)
|
|||
|
# Don't display window manager on macOS.
|
|||
|
;;
|
|||
|
|
|||
|
(*)
|
|||
|
# xprop can be used to grab the window manager's properties
|
|||
|
# which contains the window manager's name under '_NET_WM_NAME'.
|
|||
|
#
|
|||
|
# The upside to using 'xprop' is that you don't need to hardcode
|
|||
|
# a list of known window manager names. The downside is that
|
|||
|
# not all window managers conform to setting the '_NET_WM_NAME'
|
|||
|
# atom..
|
|||
|
#
|
|||
|
# List of window managers which fail to set the name atom:
|
|||
|
# catwm, fvwm, dwm, 2bwm, monster, wmaker and sowm [mine! ;)].
|
|||
|
#
|
|||
|
# The final downside to this approach is that it does _not_
|
|||
|
# support Wayland environments. The only solution which supports
|
|||
|
# Wayland is the 'ps' parsing mentioned below.
|
|||
|
#
|
|||
|
# A more naive implementation is to parse the last line of
|
|||
|
# '~/.xinitrc' to extract the second white-space separated
|
|||
|
# element.
|
|||
|
#
|
|||
|
# The issue with an approach like this is that this line data
|
|||
|
# does not always equate to the name of the window manager and
|
|||
|
# could in theory be _anything_.
|
|||
|
#
|
|||
|
# This also fails when the user launches xorg through a display
|
|||
|
# manager or other means.
|
|||
|
#
|
|||
|
#
|
|||
|
# Another naive solution is to parse 'ps' with a hardcoded list
|
|||
|
# of window managers to detect the current window manager (based
|
|||
|
# on what is running).
|
|||
|
#
|
|||
|
# The issue with this approach is the need to hardcode and
|
|||
|
# maintain a list of known window managers.
|
|||
|
#
|
|||
|
# Another issue is that process names do not always equate to
|
|||
|
# the name of the window manager. False-positives can happen too.
|
|||
|
#
|
|||
|
# This is the only solution which supports Wayland based
|
|||
|
# environments sadly. It'd be nice if some kind of standard were
|
|||
|
# established to identify Wayland environments.
|
|||
|
#
|
|||
|
# pfetch's goal is to remain _simple_, if you'd like a "full"
|
|||
|
# implementation of window manager detection use 'neofetch'.
|
|||
|
#
|
|||
|
# Neofetch use a combination of 'xprop' and 'ps' parsing to
|
|||
|
# support all window managers (including non-conforming and
|
|||
|
# Wayland) though it's a lot more complicated!
|
|||
|
|
|||
|
# Don't display window manager if X isn't running.
|
|||
|
[ "$DISPLAY" ] || return
|
|||
|
|
|||
|
# This is a two pass call to xprop. One call to get the window
|
|||
|
# manager's ID and another to print its properties.
|
|||
|
has xprop && {
|
|||
|
# The output of the ID command is as follows:
|
|||
|
# _NET_SUPPORTING_WM_CHECK: window id # 0x400000
|
|||
|
#
|
|||
|
# To extract the ID, everything before the last space
|
|||
|
# is removed.
|
|||
|
id=$(xprop -root -notype _NET_SUPPORTING_WM_CHECK)
|
|||
|
id=${id##* }
|
|||
|
|
|||
|
# The output of the property command is as follows:
|
|||
|
# _NAME 8t
|
|||
|
# _NET_WM_PID = 252
|
|||
|
# _NET_WM_NAME = "bspwm"
|
|||
|
# _NET_SUPPORTING_WM_CHECK: window id # 0x400000
|
|||
|
# WM_CLASS = "wm", "Bspwm"
|
|||
|
#
|
|||
|
# To extract the name, everything before '_NET_WM_NAME = \"'
|
|||
|
# is removed and everything after the next '"' is removed.
|
|||
|
wm=$(xprop -id "$id" -notype -len 25 -f _NET_WM_NAME 8t)
|
|||
|
}
|
|||
|
|
|||
|
# Handle cases of a window manager _not_ populating the
|
|||
|
# '_NET_WM_NAME' atom. Display nothing in this case.
|
|||
|
case $wm in
|
|||
|
(*'_NET_WM_NAME = '*)
|
|||
|
wm=${wm##*_NET_WM_NAME = \"}
|
|||
|
wm=${wm%%\"*}
|
|||
|
;;
|
|||
|
|
|||
|
(*)
|
|||
|
# Fallback to checking the process list
|
|||
|
# for the select few window managers which
|
|||
|
# don't set '_NET_WM_NAME'.
|
|||
|
while read -r ps_line; do
|
|||
|
case $ps_line in
|
|||
|
(*catwm*) wm=catwm ;;
|
|||
|
(*fvwm*) wm=fvwm ;;
|
|||
|
(*dwm*) wm=dwm ;;
|
|||
|
(*2bwm*) wm=2bwm ;;
|
|||
|
(*monsterwm*) wm=monsterwm ;;
|
|||
|
(*wmaker*) wm='Window Maker' ;;
|
|||
|
(*sowm*) wm=sowm ;;
|
|||
|
esac
|
|||
|
done <<-EOF
|
|||
|
$(ps x)
|
|||
|
EOF
|
|||
|
;;
|
|||
|
esac
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
log wm "$wm" >&6
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
get_de() {
|
|||
|
# This only supports Xorg related desktop environments though
|
|||
|
# this is fine as knowing the desktop environment on Windows,
|
|||
|
# macOS etc is useless (they'll always report the same value).
|
|||
|
#
|
|||
|
# Display the value of '$XDG_CURRENT_DESKTOP', if it's empty,
|
|||
|
# display the value of '$DESKTOP_SESSION'.
|
|||
|
log de "${XDG_CURRENT_DESKTOP:-$DESKTOP_SESSION}" >&6
|
|||
|
}
|
|||
|
|
|||
|
get_shell() {
|
|||
|
# Display the basename of the '$SHELL' environment variable.
|
|||
|
log shell "${SHELL##*/}" >&6
|
|||
|
}
|
|||
|
|
|||
|
get_editor() {
|
|||
|
# Display the value of '$VISUAL', if it's empty, display the
|
|||
|
# value of '$EDITOR'.
|
|||
|
log editor "${VISUAL:-$EDITOR}" >&6
|
|||
|
}
|
|||
|
|
|||
|
get_palette() {
|
|||
|
# Print the first 8 terminal colors. This uses the existing
|
|||
|
# sequences to change text color with a sequence prepended
|
|||
|
# to reverse the foreground and background colors.
|
|||
|
#
|
|||
|
# This allows us to save hardcoding a second set of sequences
|
|||
|
# for background colors.
|
|||
|
#
|
|||
|
# False positive.
|
|||
|
# shellcheck disable=2154
|
|||
|
{
|
|||
|
esc SGR 7
|
|||
|
palette="$e$c1 $c1 $c2 $c2 $c3 $c3 $c4 $c4 $c5 $c5 $c6 $c6 "
|
|||
|
esc SGR 0
|
|||
|
palette="$palette$e"
|
|||
|
}
|
|||
|
|
|||
|
# Print the palette with a new-line before and afterwards.
|
|||
|
printf '\n' >&6
|
|||
|
log "$palette
|
|||
|
" " " >&6
|
|||
|
}
|
|||
|
|
|||
|
get_ascii() {
|
|||
|
# This is a simple function to read the contents of
|
|||
|
# an ascii file from 'stdin'. It allows for the use
|
|||
|
# of '<<-EOF' to prevent the break in indentation in
|
|||
|
# this source code.
|
|||
|
#
|
|||
|
# This function also sets the text colors according
|
|||
|
# to the ascii color.
|
|||
|
read_ascii() {
|
|||
|
# 'PF_COL1': Set the info name color according to ascii color.
|
|||
|
# 'PF_COL3': Set the title color to some other color. ¯\_(ツ)_/¯
|
|||
|
PF_COL1=${PF_COL1:-${1:-7}}
|
|||
|
PF_COL3=${PF_COL3:-$((${1:-7}%8+1))}
|
|||
|
|
|||
|
# POSIX sh has no 'var+=' so 'var=${var}append' is used. What's
|
|||
|
# interesting is that 'var+=' _is_ supported inside '$(())'
|
|||
|
# (arithmetic) though there's no support for 'var++/var--'.
|
|||
|
#
|
|||
|
# There is also no $'\n' to add a "literal"(?) newline to the
|
|||
|
# string. The simplest workaround being to break the line inside
|
|||
|
# the string (though this has the caveat of breaking indentation).
|
|||
|
while IFS= read -r line; do
|
|||
|
ascii="$ascii$line
|
|||
|
"
|
|||
|
done
|
|||
|
}
|
|||
|
|
|||
|
# This checks for ascii art in the following order:
|
|||
|
# '$1': Argument given to 'get_ascii()' directly.
|
|||
|
# '$PF_ASCII': Environment variable set by user.
|
|||
|
# '$distro': The detected distribution name.
|
|||
|
# '$os': The name of the operating system/kernel.
|
|||
|
#
|
|||
|
# NOTE: Each ascii art below is indented using tabs, this
|
|||
|
# allows indentation to continue naturally despite
|
|||
|
# the use of '<<-EOF'.
|
|||
|
#
|
|||
|
# False positive.
|
|||
|
# shellcheck disable=2154
|
|||
|
case ${1:-${PF_ASCII:-${distro:-$os}}} in
|
|||
|
([Aa]lpine*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c4} /\\ /\\
|
|||
|
/${c7}/ ${c4}\\ \\
|
|||
|
/${c7}/ ${c4}\\ \\
|
|||
|
/${c7}// ${c4}\\ \\
|
|||
|
${c7}// ${c4}\\ \\
|
|||
|
${c4}\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Aa]ndroid*)
|
|||
|
read_ascii 2 <<-EOF
|
|||
|
${c2} ;, ,;
|
|||
|
${c2} ';,.-----.,;'
|
|||
|
${c2} ,' ',
|
|||
|
${c2} / O O \\
|
|||
|
${c2}| |
|
|||
|
${c2}'-----------------'
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Aa]rch*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c6} /\\
|
|||
|
${c6} / \\
|
|||
|
${c6} /\\ \\
|
|||
|
${c4} / \\
|
|||
|
${c4} / ,, \\
|
|||
|
${c4} / | | -\\
|
|||
|
${c4} /_-'' ''-_\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Aa]rco*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c4} /\\
|
|||
|
${c4} / \\
|
|||
|
${c4} / /\\ \\
|
|||
|
${c4} / / \\ \\
|
|||
|
${c4} / / \\ \\
|
|||
|
${c4} / / _____\\ \\
|
|||
|
${c4}/_/ \`----.\\_\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Aa]rtix*)
|
|||
|
read_ascii 6 <<-EOF
|
|||
|
${c4} /\\
|
|||
|
${c4} / \\
|
|||
|
${c4} /\`'.,\\
|
|||
|
${c4} / ',
|
|||
|
${c4} / ,\`\\
|
|||
|
${c4} / ,.'\`. \\
|
|||
|
${c4}/.,'\` \`'.\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Bb]edrock*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c7}__
|
|||
|
${c7}\\ \\___
|
|||
|
${c7} \\ _ \\
|
|||
|
${c7} \\___/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Bb]uildroot*)
|
|||
|
read_ascii 3 <<-EOF
|
|||
|
${c3} ___
|
|||
|
${c3} / \` \\
|
|||
|
${c3}| : :|
|
|||
|
${c3}-. _:__.-
|
|||
|
${c3} \` ---- \`
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Cc]ent[Oo][Ss]*)
|
|||
|
read_ascii 5 <<-EOF
|
|||
|
${c2} ____${c3}^${c5}____
|
|||
|
${c2} |\\ ${c3}|${c5} /|
|
|||
|
${c2} | \\ ${c3}|${c5} / |
|
|||
|
${c5}<---- ${c4}---->
|
|||
|
${c4} | / ${c2}|${c3} \\ |
|
|||
|
${c4} |/__${c2}|${c3}__\\|
|
|||
|
${c2} v
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Dd]ahlia*)
|
|||
|
read_ascii 1 <<-EOF
|
|||
|
${c1} _
|
|||
|
${c1} ___/ \\___
|
|||
|
${c1} | _-_ |
|
|||
|
${c1} | / \ |
|
|||
|
${c1}/ | | \\
|
|||
|
${c1}\\ | | /
|
|||
|
${c1} | \ _ _ / |
|
|||
|
${c1} |___ - ___|
|
|||
|
${c1} \\_/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Dd]ebian*)
|
|||
|
read_ascii 1 <<-EOF
|
|||
|
${c1} _____
|
|||
|
${c1} / __ \\
|
|||
|
${c1}| / |
|
|||
|
${c1}| \\___-
|
|||
|
${c1}-_
|
|||
|
${c1} --_
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Dd]ragon[Ff]ly*)
|
|||
|
read_ascii 1 <<-EOF
|
|||
|
,${c1}_${c7},
|
|||
|
('-_${c1}|${c7}_-')
|
|||
|
>--${c1}|${c7}--<
|
|||
|
(_-'${c1}|${c7}'-_)
|
|||
|
${c1}|
|
|||
|
${c1}|
|
|||
|
${c1}|
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ee]lementary*)
|
|||
|
read_ascii <<-EOF
|
|||
|
${c7} _______
|
|||
|
${c7} / ____ \\
|
|||
|
${c7}/ | / /\\
|
|||
|
${c7}|__\\ / / |
|
|||
|
${c7}\\ /__/ /
|
|||
|
${c7}\\_______/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ee]ndeavour*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c1}/${c4}\\
|
|||
|
${c1}/${c4}/ \\${c6}\\
|
|||
|
${c1}/${c4}/ \\ ${c6}\\
|
|||
|
${c1}/ ${c4}/ _) ${c6})
|
|||
|
${c1}/_${c4}/___-- ${c6}__-
|
|||
|
${c6}/____--
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ff]edora*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c4},'''''.
|
|||
|
${c4}| ,. |
|
|||
|
${c4}| | '_'
|
|||
|
${c4} ,....| |..
|
|||
|
${c4}.' ,_;| ..'
|
|||
|
${c4}| | | |
|
|||
|
${c4}| ',_,' |
|
|||
|
${c4} '. ,'
|
|||
|
${c4}'''''
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ff]ree[Bb][Ss][Dd]*)
|
|||
|
read_ascii 1 <<-EOF
|
|||
|
${c1}/\\,-'''''-,/\\
|
|||
|
${c1}\\_) (_/
|
|||
|
${c1}| |
|
|||
|
${c1}| |
|
|||
|
${c1}; ;
|
|||
|
${c1}'-_____-'
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Gg]entoo*)
|
|||
|
read_ascii 5 <<-EOF
|
|||
|
${c5} _-----_
|
|||
|
${c5}( \\
|
|||
|
${c5}\\ 0 \\
|
|||
|
${c7} \\ )
|
|||
|
${c7} / _/
|
|||
|
${c7}( _-
|
|||
|
${c7}\\____-
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Gg][Nn][Uu]*)
|
|||
|
read_ascii 3 <<-EOF
|
|||
|
${c2} _-\`\`-, ,-\`\`-_
|
|||
|
${c2} .' _-_| |_-_ '.
|
|||
|
${c2}./ /_._ _._\\ \\.
|
|||
|
${c2}: _/_._\`:'_._\\_ :
|
|||
|
${c2}\\:._/ ,\` \\ \\ \\_.:/
|
|||
|
${c2} ,-';'.@) \\ @) \\
|
|||
|
${c2} ,'/' ..- .\\,-.|
|
|||
|
${c2} /'/' \\(( \\\` ./ )
|
|||
|
${c2} '/'' \\_,----'
|
|||
|
${c2} '/'' ,;/''
|
|||
|
${c2} \`\`;'
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Gg]uix[Ss][Dd]*|[Gg]uix*)
|
|||
|
read_ascii 3 <<-EOF
|
|||
|
${c3}|.__ __.|
|
|||
|
${c3}|__ \\ / __|
|
|||
|
${c3}\\ \\ / /
|
|||
|
${c3}\\ \\ / /
|
|||
|
${c3}\\ \\ / /
|
|||
|
${c3}\\ \\/ /
|
|||
|
${c3}\\__/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Hh]aiku*)
|
|||
|
read_ascii 3 <<-EOF
|
|||
|
${c3} ,^,
|
|||
|
${c3} / \\
|
|||
|
${c3}*--_ ; ; _--*
|
|||
|
${c3}\\ '" "' /
|
|||
|
${c3}'. .'
|
|||
|
${c3}.-'" "'-.
|
|||
|
${c3}'-.__. .__.-'
|
|||
|
${c3}|_|
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Hh]ydroOS*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c1}╔╗╔╗──╔╗───╔═╦══╗
|
|||
|
${c1}║╚╝╠╦╦╝╠╦╦═╣║║══╣
|
|||
|
${c1}║╔╗║║║╬║╔╣╬║║╠══║
|
|||
|
${c1}╚╝╚╬╗╠═╩╝╚═╩═╩══╝
|
|||
|
${c1}───╚═╝
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Hh]yperbola*)
|
|||
|
read_ascii <<-EOF
|
|||
|
${c7} |\`__.\`/
|
|||
|
${c7} \____/
|
|||
|
${c7} .--.
|
|||
|
${c7} / \\
|
|||
|
${c7} / ___ \\
|
|||
|
${c7}/ .\` \`.\\
|
|||
|
${c7}/.\` \`.\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ii]glunix*)
|
|||
|
read_ascii <<-EOF
|
|||
|
${c0} |
|
|||
|
${c0} | |
|
|||
|
${c0} |
|
|||
|
${c0} | ________
|
|||
|
${c0} | /\\ | \\
|
|||
|
${c0} / \\ | \\ |
|
|||
|
${c0} / \\ \\ |
|
|||
|
${c0} / \\________\\
|
|||
|
${c0} \\ / /
|
|||
|
${c0} \\ / /
|
|||
|
${c0} \\ / /
|
|||
|
${c0} \\/________/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ii]nstant[Oo][Ss]*)
|
|||
|
read_ascii <<-EOF
|
|||
|
${c0} ,-''-,
|
|||
|
${c0}: .''. :
|
|||
|
${c0}: ',,' :
|
|||
|
${c0} '-____:__
|
|||
|
${c0} : \`.
|
|||
|
${c0} \`._.'
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ii][Rr][Ii][Xx]*)
|
|||
|
read_ascii 1 <<-EOF
|
|||
|
${c1} __
|
|||
|
${c1} \\ \\ __
|
|||
|
${c1} \\ \\ / /
|
|||
|
${c1} \\ v /
|
|||
|
${c1} / . \\
|
|||
|
${c1} /_/ \\ \\
|
|||
|
${c1} \\_\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Kk][Dd][Ee]*[Nn]eon*)
|
|||
|
read_ascii 6 <<-EOF
|
|||
|
${c7} .${c6}__${c7}.${c6}__${c7}.
|
|||
|
${c6} / _${c7}.${c6}_ \\
|
|||
|
${c6} / / \\ \\
|
|||
|
${c7} . ${c6}| ${c7}O${c6} | ${c7}.
|
|||
|
${c6} \\ \\_${c7}.${c6}_/ /
|
|||
|
${c6} \\${c7}.${c6}__${c7}.${c6}__${c7}.${c6}/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ll]inux*[Ll]ite*|[Ll]ite*)
|
|||
|
read_ascii 3 <<-EOF
|
|||
|
${c3} /\\
|
|||
|
${c3} / \\
|
|||
|
${c3} / ${c7}/ ${c3}/
|
|||
|
${c3}> ${c7}/ ${c3}/
|
|||
|
${c3}\\ ${c7}\\ ${c3}\\
|
|||
|
${c3}\\_${c7}\\${c3}_\\
|
|||
|
${c7} \\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ll]inux*[Mm]int*|[Mm]int)
|
|||
|
read_ascii 2 <<-EOF
|
|||
|
${c2} ___________
|
|||
|
${c2}|_ \\
|
|||
|
${c2}| ${c7}| _____ ${c2}|
|
|||
|
${c2}| ${c7}| | | | ${c2}|
|
|||
|
${c2}| ${c7}| | | | ${c2}|
|
|||
|
${c2}| ${c7}\\__${c7}___/ ${c2}|
|
|||
|
${c2}\\_________/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
|
|||
|
([Ll]inux*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c4} ___
|
|||
|
${c4}(${c7}.. ${c4}|
|
|||
|
${c4}(${c5}<> ${c4}|
|
|||
|
${c4}/ ${c7}__ ${c4}\\
|
|||
|
${c4}( ${c7}/ \\ ${c4}/|
|
|||
|
${c5}_${c4}/\\ ${c7}__)${c4}/${c5}_${c4})
|
|||
|
${c5}\/${c4}-____${c5}\/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Mm]ac[Oo][Ss]*|[Dd]arwin*)
|
|||
|
read_ascii 1 <<-EOF
|
|||
|
${c2} .:'
|
|||
|
${c2} _ :'_
|
|||
|
${c3} .'\`_\`-'_\`\`.
|
|||
|
${c1}:________.-'
|
|||
|
${c1}:_______:
|
|||
|
${c4} :_______\`-;
|
|||
|
${c5} \`._.-._.'
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Mm]ageia*)
|
|||
|
read_ascii 2 <<-EOF
|
|||
|
${c6} *
|
|||
|
${c6} *
|
|||
|
${c6} **
|
|||
|
${c7} /\\__/\\
|
|||
|
${c7}/ \\
|
|||
|
${c7}\\ /
|
|||
|
${c7} \\____/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Mm]anjaro*)
|
|||
|
read_ascii 2 <<-EOF
|
|||
|
${c2}||||||||| ||||
|
|||
|
${c2}||||||||| ||||
|
|||
|
${c2}|||| ||||
|
|||
|
${c2}|||| |||| ||||
|
|||
|
${c2}|||| |||| ||||
|
|||
|
${c2}|||| |||| ||||
|
|||
|
${c2}|||| |||| ||||
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Mm]inix*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c4} ,, ,,
|
|||
|
${c4};${c7},${c4} ', ,' ${c7},${c4};
|
|||
|
${c4}; ${c7}',${c4} ',,' ${c7},'${c4} ;
|
|||
|
${c4}; ${c7}',${c4} ${c7},'${c4} ;
|
|||
|
${c4}; ${c7};, '' ,;${c4} ;
|
|||
|
${c4}; ${c7};${c4};${c7}',,'${c4};${c7};${c4} ;
|
|||
|
${c4}', ${c7};${c4};; ;;${c7};${c4} ,'
|
|||
|
${c4} '${c7};${c4}' '${c7};${c4}'
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Mm][Xx]*)
|
|||
|
read_ascii <<-EOF
|
|||
|
${c7} \\\\ /
|
|||
|
${c7} \\\\/
|
|||
|
${c7} \\\\
|
|||
|
${c7} /\\/ \\\\
|
|||
|
${c7} / \\ /\\
|
|||
|
${c7} / \\/ \\
|
|||
|
${c7}/__________\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Nn]et[Bb][Ss][Dd]*)
|
|||
|
read_ascii 3 <<-EOF
|
|||
|
${c7}\\\\${c3}\`-______,----__
|
|||
|
${c7} \\\\ ${c3}__,---\`_
|
|||
|
${c7} \\\\ ${c3}\`.____
|
|||
|
${c7} \\\\${c3}-______,----\`-
|
|||
|
${c7} \\\\
|
|||
|
${c7} \\\\
|
|||
|
${c7} \\\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Nn]ix[Oo][Ss]*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c4} \\\\ \\\\ //
|
|||
|
${c4} ==\\\\__\\\\/ //
|
|||
|
${c4} // \\\\//
|
|||
|
${c4}==// //==
|
|||
|
${c4} //\\\\___//
|
|||
|
${c4}// /\\\\ \\\\==
|
|||
|
${c4} // \\\\ \\\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Oo]pen[Bb][Ss][Dd]*)
|
|||
|
read_ascii 3 <<-EOF
|
|||
|
${c3} _____
|
|||
|
${c3} \\- -/
|
|||
|
${c3} \\_/ \\
|
|||
|
${c3} | ${c7}O O${c3} |
|
|||
|
${c3} |_ < ) 3 )
|
|||
|
${c3} / \\ /
|
|||
|
${c3} /-_____-\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Oo]pen[Ss][Uu][Ss][Ee]*[Tt]umbleweed*)
|
|||
|
read_ascii 2 <<-EOF
|
|||
|
${c2} _____ ______
|
|||
|
${c2} / ____\\ / ____ \\
|
|||
|
${c2}/ / \`/ / \\ \\
|
|||
|
${c2}\\ \\____/ /,____/ /
|
|||
|
${c2} \\______/ \\_____/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Oo]pen[Ss][Uu][Ss][Ee]*|[Oo]pen*SUSE*|SUSE*|suse*)
|
|||
|
read_ascii 2 <<-EOF
|
|||
|
${c2} _______
|
|||
|
${c2}__| __ \\
|
|||
|
${c2} / .\\ \\
|
|||
|
${c2} \\__/ |
|
|||
|
${c2} _______|
|
|||
|
${c2} \\_______
|
|||
|
${c2}__________/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Oo]pen[Ww]rt*)
|
|||
|
read_ascii 1 <<-EOF
|
|||
|
${c1} _______
|
|||
|
${c1}| |.-----.-----.-----.
|
|||
|
${c1}| - || _ | -__| |
|
|||
|
${c1}|_______|| __|_____|__|__|
|
|||
|
${c1} ________|__| __
|
|||
|
${c1}| | | |.----.| |_
|
|||
|
${c1}| | | || _|| _|
|
|||
|
${c1}|________||__| |____|
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Pp]arabola*)
|
|||
|
read_ascii 5 <<-EOF
|
|||
|
${c5} __ __ __ _
|
|||
|
${c5}.\`_//_//_/ / \`.
|
|||
|
${c5} / .\`
|
|||
|
${c5} / .\`
|
|||
|
${c5} /.\`
|
|||
|
${c5} /\`
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Pp]op!_[Oo][Ss]*)
|
|||
|
read_ascii 6 <<-EOF
|
|||
|
${c6}______
|
|||
|
${c6}\\ _ \\ __
|
|||
|
${c6}\\ \\ \\ \\ / /
|
|||
|
${c6}\\ \\_\\ \\ / /
|
|||
|
${c6}\\ ___\\ /_/
|
|||
|
${c6} \\ \\ _
|
|||
|
${c6} __\\_\\__(_)_
|
|||
|
${c6}(___________)
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Pp]ure[Oo][Ss]*)
|
|||
|
read_ascii <<-EOF
|
|||
|
${c7} _____________
|
|||
|
${c7}| _________ |
|
|||
|
${c7}| | | |
|
|||
|
${c7}| | | |
|
|||
|
${c7}| |_________| |
|
|||
|
${c7}|_____________|
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Rr]aspbian*)
|
|||
|
read_ascii 1 <<-EOF
|
|||
|
${c2} __ __
|
|||
|
${c2} (_\\)(/_)
|
|||
|
${c1} (_(__)_)
|
|||
|
${c1}(_(_)(_)_)
|
|||
|
${c1} (_(__)_)
|
|||
|
${c1} (__)
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ss]lackware*)
|
|||
|
read_ascii 4 <<-EOF
|
|||
|
${c4} ________
|
|||
|
${c4} / ______|
|
|||
|
${c4} | |______
|
|||
|
${c4} \\______ \\
|
|||
|
${c4} ______| |
|
|||
|
${c4}| |________/
|
|||
|
${c4}|____________
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Ss]un[Oo][Ss]|[Ss]olaris*)
|
|||
|
read_ascii 3 <<-EOF
|
|||
|
${c3} . .; .
|
|||
|
${c3} . :; :: ;: .
|
|||
|
${c3} .;. .. .. .;.
|
|||
|
${c3}.. .. .. ..
|
|||
|
${c3} .;, ,;.
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Uu]buntu*)
|
|||
|
read_ascii 3 <<-EOF
|
|||
|
${c3} _
|
|||
|
${c3} ---(_)
|
|||
|
${c3} _/ --- \\
|
|||
|
${c3}(_) | |
|
|||
|
${c3} \\ --- _/
|
|||
|
${c3} ---(_)
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Vv]oid*)
|
|||
|
read_ascii 2 <<-EOF
|
|||
|
${c2} _______
|
|||
|
${c2} _ \\______ -
|
|||
|
${c2}| \\ ___ \\ |
|
|||
|
${c2}| | / \ | |
|
|||
|
${c2}| | \___/ | |
|
|||
|
${c2}| \\______ \\_|
|
|||
|
${c2} -_______\\
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
([Xx]eonix*)
|
|||
|
read_ascii 2 <<-EOF
|
|||
|
${c2} ___ ___
|
|||
|
${c2}___ \ \/ / ___
|
|||
|
${c2}\ \ \ / / /
|
|||
|
${c2} \ \/ \/ /
|
|||
|
${c2} \ /\ /
|
|||
|
${c2} \__/ \__/
|
|||
|
EOF
|
|||
|
;;
|
|||
|
|
|||
|
(*)
|
|||
|
# On no match of a distribution ascii art, this function calls
|
|||
|
# itself again, this time to look for a more generic OS related
|
|||
|
# ascii art (KISS Linux -> Linux).
|
|||
|
[ "$1" ] || {
|
|||
|
get_ascii "$os"
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
printf 'error: %s is not currently supported.\n' "$os" >&6
|
|||
|
printf 'error: Open an issue for support to be added.\n' >&6
|
|||
|
exit 1
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
# Store the "width" (longest line) and "height" (number of lines)
|
|||
|
# of the ascii art for positioning. This script prints to the screen
|
|||
|
# *almost* like a TUI does. It uses escape sequences to allow dynamic
|
|||
|
# printing of the information through user configuration.
|
|||
|
#
|
|||
|
# Iterate over each line of the ascii art to retrieve the above
|
|||
|
# information. The 'sed' is used to strip '\033[3Xm' color codes from
|
|||
|
# the ascii art so they don't affect the width variable.
|
|||
|
while read -r line; do
|
|||
|
ascii_height=$((${ascii_height:-0} + 1))
|
|||
|
|
|||
|
# This was a ternary operation but they aren't supported in
|
|||
|
# Minix's shell.
|
|||
|
[ "${#line}" -gt "${ascii_width:-0}" ] &&
|
|||
|
ascii_width=${#line}
|
|||
|
|
|||
|
# Using '<<-EOF' is the only way to loop over a command's
|
|||
|
# output without the use of a pipe ('|').
|
|||
|
# This ensures that any variables defined in the while loop
|
|||
|
# are still accessible in the script.
|
|||
|
done <<-EOF
|
|||
|
$(printf %s "$ascii" | sed 's/\[3.m//g')
|
|||
|
EOF
|
|||
|
|
|||
|
# Add a gap between the ascii art and the information.
|
|||
|
ascii_width=$((ascii_width + 4))
|
|||
|
|
|||
|
# Print the ascii art and position the cursor back where we
|
|||
|
# started prior to printing it.
|
|||
|
{
|
|||
|
esc_p SGR 1
|
|||
|
printf '%s' "$ascii"
|
|||
|
esc_p SGR 0
|
|||
|
esc_p CUU "$ascii_height"
|
|||
|
} >&6
|
|||
|
}
|
|||
|
|
|||
|
main() {
|
|||
|
[ "$1" = --version ] && {
|
|||
|
printf 'pfetch 0.7.0\n'
|
|||
|
exit 0
|
|||
|
}
|
|||
|
|
|||
|
# Hide 'stderr' unless the first argument is '-v'. This saves
|
|||
|
# polluting the script with '2>/dev/null'.
|
|||
|
[ "$1" = -v ] || {
|
|||
|
exec 2>/dev/null
|
|||
|
}
|
|||
|
|
|||
|
# Hide 'stdout' and selectively print to it using '>&6'.
|
|||
|
# This gives full control over what it displayed on the screen.
|
|||
|
exec 6>&1 >/dev/null
|
|||
|
|
|||
|
# Store raw escape sequence character for later reuse.
|
|||
|
esc_c=$(printf '\033')
|
|||
|
|
|||
|
# Allow the user to execute their own script and modify or
|
|||
|
# extend pfetch's behavior.
|
|||
|
# shellcheck source=/dev/null
|
|||
|
. "${PF_SOURCE:-/dev/null}" ||:
|
|||
|
|
|||
|
# Ensure that the 'TMPDIR' is writable as heredocs use it and
|
|||
|
# fail without the write permission. This was found to be the
|
|||
|
# case on Android where the temporary directory requires root.
|
|||
|
[ -w "${TMPDIR:-/tmp}" ] || export TMPDIR=~
|
|||
|
|
|||
|
# Generic color list.
|
|||
|
# Disable warning about unused variables.
|
|||
|
# shellcheck disable=2034
|
|||
|
for _c in c1 c2 c3 c4 c5 c6 c7 c8; do
|
|||
|
esc SGR "3${_c#?}" 0
|
|||
|
export "$_c=$e"
|
|||
|
done
|
|||
|
|
|||
|
# Disable line wrapping and catch the EXIT signal to enable it again
|
|||
|
# on exit. Ideally you'd somehow query the current value and retain
|
|||
|
# it but I'm yet to see this irk anyone.
|
|||
|
esc_p DECAWM l >&6
|
|||
|
trap 'esc_p DECAWM h >&6' EXIT
|
|||
|
|
|||
|
# Store the output of 'uname' to avoid calling it multiple times
|
|||
|
# throughout the script. 'read <<EOF' is the simplest way of reading
|
|||
|
# a command into a list of variables.
|
|||
|
read -r os kernel arch <<-EOF
|
|||
|
$(uname -srm)
|
|||
|
EOF
|
|||
|
|
|||
|
# Always run 'get_os' for the purposes of detecting which ascii
|
|||
|
# art to display.
|
|||
|
get_os
|
|||
|
|
|||
|
# Allow the user to specify the order and inclusion of information
|
|||
|
# functions through the 'PF_INFO' environment variable.
|
|||
|
# shellcheck disable=2086
|
|||
|
{
|
|||
|
# Disable globbing and set the positional parameters to the
|
|||
|
# contents of 'PF_INFO'.
|
|||
|
set -f
|
|||
|
set +f -- ${PF_INFO-ascii title os host kernel uptime pkgs memory}
|
|||
|
|
|||
|
# Iterate over the info functions to determine the lengths of the
|
|||
|
# "info names" for output alignment. The option names and subtitles
|
|||
|
# match 1:1 so this is thankfully simple.
|
|||
|
for info do
|
|||
|
command -v "get_$info" >/dev/null || continue
|
|||
|
|
|||
|
# This was a ternary operation but they aren't supported in
|
|||
|
# Minix's shell.
|
|||
|
[ "${#info}" -gt "${info_length:-0}" ] &&
|
|||
|
info_length=${#info}
|
|||
|
done
|
|||
|
|
|||
|
# Add an additional space of length to act as a gap.
|
|||
|
info_length=$((info_length + 1))
|
|||
|
|
|||
|
# Iterate over the above list and run any existing "get_" functions.
|
|||
|
for info do
|
|||
|
"get_$info"
|
|||
|
done
|
|||
|
}
|
|||
|
|
|||
|
# Position the cursor below both the ascii art and information lines
|
|||
|
# according to the height of both. If the information exceeds the ascii
|
|||
|
# art in height, don't touch the cursor (0/unset), else move it down
|
|||
|
# N lines.
|
|||
|
#
|
|||
|
# This was a ternary operation but they aren't supported in Minix's shell.
|
|||
|
[ "${info_height:-0}" -lt "${ascii_height:-0}" ] &&
|
|||
|
cursor_pos=$((ascii_height - info_height))
|
|||
|
|
|||
|
# Print '$cursor_pos' amount of newlines to correctly position the
|
|||
|
# cursor. This used to be a 'printf $(seq X X)' however 'seq' is only
|
|||
|
# typically available (by default) on GNU based systems!
|
|||
|
while [ "${i:=0}" -le "${cursor_pos:-0}" ]; do
|
|||
|
printf '\n'
|
|||
|
i=$((i + 1))
|
|||
|
done >&6
|
|||
|
}
|
|||
|
|
|||
|
main "$@"
|