2019-09-24 09:33:23 +02:00
|
|
|
|
#!/bin/sh
|
|
|
|
|
#
|
|
|
|
|
# pfetch - Simple POSIX sh fetch script.
|
|
|
|
|
|
|
|
|
|
log() {
|
2019-09-24 11:47:47 +02:00
|
|
|
|
# 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]).
|
|
|
|
|
#
|
2019-09-24 17:30:44 +02:00
|
|
|
|
# When 'log()' has executed, the cursor is then located at marker $[4].
|
2019-09-24 11:47:47 +02:00
|
|
|
|
# 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.
|
|
|
|
|
#
|
2019-09-24 17:32:27 +02:00
|
|
|
|
# However, if the information printed is "taller" (takes up more lines)
|
|
|
|
|
# than the ascii art, the cursor isn't moved at all!
|
|
|
|
|
#
|
2019-09-24 11:47:47 +02:00
|
|
|
|
# Once the cursor is at marker $[6], the script exits. This is the gist
|
|
|
|
|
# of how this "dynamic" printing and layout works.
|
|
|
|
|
#
|
2019-09-24 11:59:56 +02:00
|
|
|
|
# This method allows ascii art to be stored without markers for info
|
|
|
|
|
# and it allows for easy swapping of info order and amount.
|
2019-09-24 11:47:47 +02:00
|
|
|
|
#
|
|
|
|
|
# $[2] ___ $[3] goldie@KISS
|
|
|
|
|
# $[4](.· | $[5] os KISS Linux
|
|
|
|
|
# (<> |
|
|
|
|
|
# / __ \
|
|
|
|
|
# ( / \ /|
|
|
|
|
|
# _/\ __)/_)
|
|
|
|
|
# \/-____\/
|
|
|
|
|
# $[1]
|
|
|
|
|
#
|
|
|
|
|
# $[6] /home/goldie $
|
2019-09-24 19:17:57 +02:00
|
|
|
|
|
|
|
|
|
# Move the cursor to the right, the width of the ascii art with an
|
|
|
|
|
# additional gap for text spacing.
|
|
|
|
|
printf '[%sC' "${ascii_width--1}"
|
|
|
|
|
|
|
|
|
|
# Print the info name and color the text.
|
|
|
|
|
printf '[3%s;1m%s[m' "${PF_COL1-4}" "$1"
|
|
|
|
|
|
|
|
|
|
# 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.
|
|
|
|
|
printf '[%sD[%sC' "${#1}" "${PF_ALIGN-$info_length}"
|
|
|
|
|
|
|
|
|
|
# Print the info data, color it and strip all leading whitespace
|
|
|
|
|
# from the string.
|
|
|
|
|
printf '[3%sm%s[m\n' "${PF_COL2-7}" "${2#${2%%[![:space:]]*}}"
|
2019-09-24 11:01:34 +02:00
|
|
|
|
|
|
|
|
|
# Keep track of the number of times 'log()' has been run.
|
2019-09-24 17:22:24 +02:00
|
|
|
|
: $((info_height+=1))
|
2019-09-24 09:33:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 10:13:40 +02:00
|
|
|
|
get_title() {
|
|
|
|
|
# Username is retrieved by first checking '$USER' with a fallback
|
|
|
|
|
# to the 'whoami' command.
|
2019-09-24 17:25:49 +02:00
|
|
|
|
user=${USER:-$(whoami)}
|
|
|
|
|
|
2019-09-24 10:13:40 +02:00
|
|
|
|
# Hostname is retrieved by first checking '$HOSTNAME' with a fallback
|
|
|
|
|
# to the 'hostname' command.
|
|
|
|
|
#
|
2019-09-24 10:25:06 +02:00
|
|
|
|
# Disable the warning about '$HOSTNAME' being undefined in POSIX sh as
|
|
|
|
|
# it is intended for allowing the user to overwrite the value on invocation.
|
2019-09-24 10:13:40 +02:00
|
|
|
|
# shellcheck disable=SC2039
|
2019-09-24 17:25:49 +02:00
|
|
|
|
host=${HOSTNAME:-${hostname:-$(hostname)}}
|
|
|
|
|
|
2019-09-24 17:48:03 +02:00
|
|
|
|
log "[3${PF_COL3:-1}m${user}${c7}@[3${PF_COL3:-1}m${host}"
|
2019-09-24 10:13:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 17:48:03 +02:00
|
|
|
|
get_os() {
|
2019-09-24 15:40:41 +02:00
|
|
|
|
# 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"
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 12:34:05 +02:00
|
|
|
|
case $os in
|
2019-09-24 15:15:35 +02:00
|
|
|
|
Linux*)
|
2019-09-24 20:17:25 +02:00
|
|
|
|
# TODO: Some distributions don't support '/etc/os-release'.
|
|
|
|
|
# Bedrock support is something I'd like to add for example.
|
|
|
|
|
|
2019-09-24 14:01:41 +02:00
|
|
|
|
# Disable warning about shellcheck not being able
|
|
|
|
|
# to read '/etc/os-release'. This is fine.
|
|
|
|
|
# shellcheck source=/dev/null
|
2019-09-24 09:33:23 +02:00
|
|
|
|
. /etc/os-release && distro=$PRETTY_NAME
|
2019-09-24 20:17:25 +02:00
|
|
|
|
|
2019-09-24 21:43:46 +02:00
|
|
|
|
# Special cases for distributions which don't follow.
|
|
|
|
|
# the '/etc/os-release' "standard".
|
2019-09-24 20:17:25 +02:00
|
|
|
|
command -v crux >/dev/null && distro=$(crux)
|
2019-09-24 21:43:46 +02:00
|
|
|
|
command -v guix >/dev/null && distro='Guix System'
|
2019-09-24 09:33:23 +02:00
|
|
|
|
;;
|
2019-09-24 15:43:28 +02:00
|
|
|
|
|
2019-09-24 19:35:03 +02:00
|
|
|
|
Darwin*)
|
|
|
|
|
# TODO: Parse '/System/Library/CoreServices/SystemVersion.plist'
|
|
|
|
|
# to grab the full distribution name, version and build.
|
|
|
|
|
distro=macOS
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 15:43:28 +02:00
|
|
|
|
*)
|
|
|
|
|
# Catch all to ensure '$distro' is never blank.
|
2019-09-24 19:35:03 +02:00
|
|
|
|
# This also handles the BSDs.
|
2019-09-24 19:26:50 +02:00
|
|
|
|
distro="$os $kernel"
|
2019-09-24 15:43:28 +02:00
|
|
|
|
;;
|
2019-09-24 09:33:23 +02:00
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 09:46:56 +02:00
|
|
|
|
get_kernel() {
|
2019-09-24 19:26:50 +02:00
|
|
|
|
# '$kernel' is the cached output of 'uname -r'.
|
|
|
|
|
case $os in
|
2019-09-24 19:35:38 +02:00
|
|
|
|
# Don't print kernel output on BSD systems as the
|
2019-09-24 19:26:50 +02:00
|
|
|
|
# OS name includes it.
|
2019-09-24 20:05:15 +02:00
|
|
|
|
*BSD*) ;;
|
2019-09-24 19:26:50 +02:00
|
|
|
|
|
|
|
|
|
*)
|
|
|
|
|
log kernel "$kernel"
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2019-09-24 09:46:56 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 21:52:13 +02:00
|
|
|
|
get_shell() {
|
|
|
|
|
log shell "${SHELL##*/}"
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 12:06:41 +02:00
|
|
|
|
get_host() {
|
2019-09-24 12:34:05 +02:00
|
|
|
|
case $os in
|
2019-09-24 15:15:35 +02:00
|
|
|
|
Linux*)
|
2019-09-24 12:50:28 +02:00
|
|
|
|
# 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"
|
2019-09-24 12:06:41 +02:00
|
|
|
|
;;
|
2019-09-24 20:05:15 +02:00
|
|
|
|
|
|
|
|
|
Darwin*)
|
|
|
|
|
host=$(sysctl -n hw.model)
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
*BSD*)
|
|
|
|
|
host=$(sysctl -n hw.vendor hw.product)
|
|
|
|
|
;;
|
2019-09-24 12:06:41 +02:00
|
|
|
|
esac
|
|
|
|
|
|
2019-09-24 12:38:46 +02:00
|
|
|
|
log host "$host"
|
2019-09-24 12:06:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 09:46:56 +02:00
|
|
|
|
get_uptime() {
|
2019-09-24 09:53:49 +02:00
|
|
|
|
# Uptime works by retrieving the data in total seconds and then
|
|
|
|
|
# converting that data into days, hours and minutes using simple
|
|
|
|
|
# math.
|
2019-09-24 12:34:05 +02:00
|
|
|
|
case $os in
|
2019-09-24 15:15:35 +02:00
|
|
|
|
Linux*)
|
2019-09-24 09:46:56 +02:00
|
|
|
|
IFS=. read -r s _ < /proc/uptime
|
|
|
|
|
;;
|
2019-09-24 19:35:03 +02:00
|
|
|
|
|
2019-09-24 20:05:15 +02:00
|
|
|
|
Darwin*|*BSD*)
|
2019-09-24 19:56:29 +02:00
|
|
|
|
s=$(sysctl -n kern.boottime)
|
2019-09-24 19:35:03 +02:00
|
|
|
|
|
|
|
|
|
# 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.
|
2019-09-24 19:36:15 +02:00
|
|
|
|
s=$(($(date +%s) - s))
|
2019-09-24 19:35:03 +02:00
|
|
|
|
;;
|
2019-09-24 09:46:56 +02:00
|
|
|
|
esac
|
|
|
|
|
|
2019-09-24 09:53:49 +02:00
|
|
|
|
# Convert the uptime from seconds into days, hours and minutes.
|
2019-09-24 09:46:56 +02:00
|
|
|
|
d=$((s / 60 / 60 / 24))
|
|
|
|
|
h=$((s / 60 / 60 % 24))
|
|
|
|
|
m=$((s / 60 % 60))
|
|
|
|
|
|
2019-09-24 09:53:49 +02:00
|
|
|
|
# Only append days, hours and minutes if they're non-zero.
|
2019-09-24 09:46:56 +02:00
|
|
|
|
[ "$d" = 0 ] || uptime="${uptime}${d}d "
|
|
|
|
|
[ "$h" = 0 ] || uptime="${uptime}${h}h "
|
|
|
|
|
[ "$m" = 0 ] || uptime="${uptime}${m}m "
|
|
|
|
|
|
2019-09-24 10:25:06 +02:00
|
|
|
|
log uptime "${uptime:-0m}"
|
2019-09-24 09:46:56 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 13:41:20 +02:00
|
|
|
|
get_pkgs() {
|
2019-09-24 12:23:19 +02:00
|
|
|
|
# Simple function to avoid '>/dev/null' spam.
|
|
|
|
|
# This checks to see if a command is in '$PATH'.
|
|
|
|
|
has() { command -v "$1" >/dev/null; }
|
|
|
|
|
|
|
|
|
|
# This works by first checking for which package managers are
|
|
|
|
|
# isntalled 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.
|
|
|
|
|
packages=$(
|
2019-09-24 12:34:05 +02:00
|
|
|
|
case $os in
|
2019-09-24 15:15:35 +02:00
|
|
|
|
Linux*)
|
2019-09-24 12:23:19 +02:00
|
|
|
|
# Commands which print packages one per line.
|
|
|
|
|
has kiss && kiss l
|
|
|
|
|
has bonsai && bonsai list
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
# Directories containing packages.
|
|
|
|
|
has brew && printf '%s\n' "$(brew --cellar)/"*
|
|
|
|
|
has emerge && printf '%s\n' /var/db/pkg/*/*/
|
2019-09-24 21:43:46 +02:00
|
|
|
|
|
|
|
|
|
# GUIX requires two commands.
|
|
|
|
|
has guix && guix package -p /run/current-system/profile -I
|
|
|
|
|
has guix && guix package -I
|
2019-09-24 12:23:19 +02:00
|
|
|
|
;;
|
2019-09-24 19:40:28 +02:00
|
|
|
|
|
|
|
|
|
Darwin*)
|
|
|
|
|
# Commands which print packages one per line.
|
|
|
|
|
has pkgin && pkgin list
|
|
|
|
|
has port && port installed
|
|
|
|
|
|
|
|
|
|
# Directories containing packages.
|
|
|
|
|
has brew && printf '%s\n' /usr/local/Cellar/*
|
|
|
|
|
;;
|
2019-09-24 19:45:58 +02:00
|
|
|
|
|
2019-09-24 20:08:33 +02:00
|
|
|
|
FreeBSD*)
|
2019-09-24 19:45:58 +02:00
|
|
|
|
# Commands which print packages one per line.
|
|
|
|
|
has pkg && pkg info
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 20:05:15 +02:00
|
|
|
|
*BSD*)
|
2019-09-24 19:45:58 +02:00
|
|
|
|
# Commands which print packages one per line.
|
|
|
|
|
has pkginfo && pkginfo -i
|
|
|
|
|
has pkg && pkg list
|
2019-09-24 21:52:13 +02:00
|
|
|
|
has pkg_info && pkg_info
|
2019-09-24 19:45:58 +02:00
|
|
|
|
;;
|
2019-09-24 12:23:19 +02:00
|
|
|
|
esac | wc -l
|
|
|
|
|
)
|
2019-09-24 12:06:41 +02:00
|
|
|
|
|
|
|
|
|
log pkgs "$packages"
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 10:03:33 +02:00
|
|
|
|
get_memory() {
|
2019-09-24 12:34:05 +02:00
|
|
|
|
case $os in
|
2019-09-24 10:03:33 +02:00
|
|
|
|
# Used memory is calculated using the following "formula" (Linux):
|
|
|
|
|
# MemUsed = MemTotal + Shmem - MemFree - Buffers - Cached - SReclaimable
|
|
|
|
|
# Source: https://github.com/KittyKatt/screenFetch/issues/386
|
2019-09-24 15:15:35 +02:00
|
|
|
|
Linux*)
|
2019-09-24 10:03:33 +02:00
|
|
|
|
# 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))
|
2019-09-24 19:46:50 +02:00
|
|
|
|
mem_full=$val
|
2019-09-24 10:03:33 +02:00
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
Shmem)
|
|
|
|
|
mem_used=$((mem_used + val))
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
MemFree|Buffers|Cached|SReclaimable)
|
|
|
|
|
mem_used=$((mem_used - val))
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
done < /proc/meminfo
|
|
|
|
|
|
|
|
|
|
mem_used=$((mem_used / 1024))
|
2019-09-24 19:46:50 +02:00
|
|
|
|
mem_full=$((mem_full / 1024))
|
2019-09-24 10:03:33 +02:00
|
|
|
|
;;
|
2019-09-24 19:56:29 +02:00
|
|
|
|
|
|
|
|
|
Darwin*)
|
|
|
|
|
# If you run macOS and can send me the full output of
|
|
|
|
|
# 'vm_stat' I'll be able to add full support here.
|
|
|
|
|
mem_full=$(($(sysctl -n hw.memsize) / 1024 / 1024))
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 20:03:06 +02:00
|
|
|
|
OpenBSD*)
|
|
|
|
|
# If you run OpenBSD and can send me the full output of
|
|
|
|
|
# 'vm_stat' I'll be able to add full support here.
|
|
|
|
|
mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024))
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 20:08:33 +02:00
|
|
|
|
FreeBSD*)
|
|
|
|
|
# If you run FreeBSD and can help me get
|
2019-09-24 20:03:06 +02:00
|
|
|
|
# the used memory amount, I'll be able to add support here.
|
|
|
|
|
mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024))
|
|
|
|
|
;;
|
2019-09-24 10:03:33 +02:00
|
|
|
|
esac
|
|
|
|
|
|
2019-09-24 19:56:29 +02:00
|
|
|
|
log memory "${mem_used:-?}MiB / ${mem_full:-?}MiB"
|
2019-09-24 10:03:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 11:01:34 +02:00
|
|
|
|
get_ascii() {
|
2019-09-24 17:00:47 +02:00
|
|
|
|
# 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.
|
|
|
|
|
read_ascii() {
|
2019-09-24 17:48:03 +02:00
|
|
|
|
# 'PF_COL1': Set the info name color according to ascii color.
|
|
|
|
|
# 'PF_COL3': Set the title color to some other color. ¯\_(ツ)_/¯
|
2019-09-24 21:32:09 +02:00
|
|
|
|
PF_COL1=${PF_COL1:-${1:-7}}
|
|
|
|
|
PF_COL3=${PF_COL3:-$((${1:-7}%8+1))}
|
2019-09-24 17:48:03 +02:00
|
|
|
|
|
2019-09-24 17:00:47 +02:00
|
|
|
|
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'.
|
2019-09-24 15:40:41 +02:00
|
|
|
|
case ${1:-${PF_ASCII:-${distro:-$os}}} in
|
|
|
|
|
[Aa]lpine*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 4 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c4} /\\ /\\
|
|
|
|
|
/${c7}/ ${c4}\\ \\
|
|
|
|
|
/${c7}/ ${c4}\\ \\
|
|
|
|
|
/${c7}// ${c4}\\ \\
|
|
|
|
|
${c7}// ${c4}\\ \\
|
|
|
|
|
\\
|
|
|
|
|
EOF
|
2019-09-24 15:40:41 +02:00
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
[Aa]rch*)
|
2019-09-24 21:14:24 +02:00
|
|
|
|
read_ascii 4 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c6} /\\
|
|
|
|
|
/^^\\
|
|
|
|
|
/\\ \\
|
|
|
|
|
/${c7} __ \\
|
|
|
|
|
/ ( ) \\
|
|
|
|
|
/ __| |__\\\\
|
|
|
|
|
/// \\\\\\
|
|
|
|
|
EOF
|
2019-09-24 15:40:41 +02:00
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:14:24 +02:00
|
|
|
|
[Aa]rco*)
|
|
|
|
|
read_ascii 4 <<-EOF
|
|
|
|
|
${c4} /\\
|
|
|
|
|
/ \\
|
|
|
|
|
/ /\\ \\
|
|
|
|
|
/ / \\ \\
|
|
|
|
|
/ / \\ \\
|
|
|
|
|
/ / _____\\ \\
|
|
|
|
|
/_/ \`----.\\_\\
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:12:20 +02:00
|
|
|
|
[Aa]rtix*)
|
|
|
|
|
read_ascii 6 <<-EOF
|
|
|
|
|
${c4} /\\
|
|
|
|
|
/ \\
|
|
|
|
|
/\`'.,\\
|
|
|
|
|
/ ',
|
|
|
|
|
/ ,\`\\
|
|
|
|
|
/ ,.'\`. \\
|
|
|
|
|
/.,'\` \`'.\\
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:03:18 +02:00
|
|
|
|
[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
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 15:40:41 +02:00
|
|
|
|
[Dd]ebian*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 1 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c1} _____
|
|
|
|
|
/ __ \\
|
|
|
|
|
| / |
|
|
|
|
|
| \\___-
|
|
|
|
|
-_
|
|
|
|
|
--_
|
|
|
|
|
EOF
|
2019-09-24 15:40:41 +02:00
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:47:11 +02:00
|
|
|
|
[Ee]lementary*)
|
|
|
|
|
read_ascii <<-EOF
|
|
|
|
|
${c7} _______
|
|
|
|
|
/ ____ \\
|
|
|
|
|
/ | / /\\
|
|
|
|
|
|__\\ / / |
|
|
|
|
|
\\ /__/ /
|
|
|
|
|
\\_______/
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 15:40:41 +02:00
|
|
|
|
[Ff]edora*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 4 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c7} _____
|
|
|
|
|
/ __)${c4}\\${c7}
|
|
|
|
|
| / ${c4}\\ \\${c7}
|
|
|
|
|
${c4}__${c7}_| |_${c4}_/ /${c7}
|
|
|
|
|
${c4}/ ${c7}(_ _)${c4}_/${c7}
|
|
|
|
|
${c4}/ /${c7} | |
|
|
|
|
|
${c4}\\ \\${c7}__/ |
|
|
|
|
|
${c4}\\${c7}(_____/
|
|
|
|
|
EOF
|
2019-09-24 15:40:41 +02:00
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
[Ff]ree[Bb][Ss][Dd]*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 1 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c1} /\\ _____ /\\
|
|
|
|
|
\\_) (_/
|
|
|
|
|
/ \\
|
|
|
|
|
| |
|
|
|
|
|
| |
|
|
|
|
|
\ /
|
|
|
|
|
--_____--
|
|
|
|
|
EOF
|
2019-09-24 15:40:41 +02:00
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
[Gg]entoo*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 5 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c5} _-----_
|
|
|
|
|
( \\
|
|
|
|
|
\\ 0 \\
|
|
|
|
|
${c7} \\ )
|
|
|
|
|
/ _/
|
|
|
|
|
( _-
|
|
|
|
|
\\____-
|
|
|
|
|
EOF
|
2019-09-24 15:40:41 +02:00
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:43:46 +02:00
|
|
|
|
[Gg]uix[Ss][Dd]*|guix*)
|
|
|
|
|
read_ascii 3 <<-EOF
|
|
|
|
|
${c3}|.__ __.|
|
|
|
|
|
|__ \\ / __|
|
|
|
|
|
\\ \\ / /
|
|
|
|
|
\\ \\ / /
|
|
|
|
|
\\ \\ / /
|
|
|
|
|
\\ \\/ /
|
|
|
|
|
\\__/
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:36:45 +02:00
|
|
|
|
[Hh]yperbola*)
|
|
|
|
|
read_ascii <<-EOF
|
|
|
|
|
${c7} |\`__.\`/
|
|
|
|
|
\____/
|
|
|
|
|
.--.
|
|
|
|
|
/ \\
|
|
|
|
|
/ ___ \\
|
|
|
|
|
/ .\` \`.\\
|
|
|
|
|
/.\` \`.\\
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 20:52:01 +02:00
|
|
|
|
[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
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:18:43 +02:00
|
|
|
|
[Ll]inux*[Ll]ite*)
|
|
|
|
|
read_ascii 3 <<-EOF
|
|
|
|
|
${c3} /\\
|
|
|
|
|
/ \\
|
|
|
|
|
/ ${c7}/ ${c3}/
|
|
|
|
|
> ${c7}/ ${c3}/
|
|
|
|
|
\\ ${c7}\\ ${c3}\\
|
|
|
|
|
\\_${c7}\\${c3}_\\
|
|
|
|
|
${c7} \\
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 15:40:41 +02:00
|
|
|
|
[Ll]inux*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 4 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c4} ___
|
|
|
|
|
(${c7}.· ${c4}|
|
|
|
|
|
(${c5}<> ${c4}|
|
|
|
|
|
/ ${c7}__ ${c4}\\
|
|
|
|
|
( ${c7}/ \\ ${c4}/|
|
|
|
|
|
${c5}_${c4}/\\ ${c7}__)${c4}/${c5}_${c4})
|
|
|
|
|
${c5}\/${c4}-____${c5}\/
|
|
|
|
|
EOF
|
2019-09-24 11:01:34 +02:00
|
|
|
|
;;
|
2019-09-24 15:06:10 +02:00
|
|
|
|
|
2019-09-24 19:35:03 +02:00
|
|
|
|
[Mm]ac[Oo][Ss]*|[Dd]arwin*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 1 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c1} .:'
|
|
|
|
|
_ :'_
|
|
|
|
|
${c2} .'\`_\`-'_\`\`.
|
|
|
|
|
:________.-'
|
|
|
|
|
${c3}:_______:
|
|
|
|
|
${c4} :_______\`-;
|
|
|
|
|
${c5} \`._.-._.'
|
|
|
|
|
EOF
|
2019-09-24 15:40:41 +02:00
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:34:28 +02:00
|
|
|
|
[Mm]ageia*)
|
|
|
|
|
read_ascii 2 <<-EOF
|
|
|
|
|
${c6} *
|
|
|
|
|
*
|
|
|
|
|
**
|
|
|
|
|
${c7} /\\__/\\
|
|
|
|
|
/ \\
|
|
|
|
|
\\ /
|
|
|
|
|
\\____/
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
[Mm]anjaro*)
|
|
|
|
|
read_ascii 2 <<-EOF
|
|
|
|
|
${c2}||||||||| ||||
|
|
|
|
|
||||||||| ||||
|
|
|
|
|
|||| ||||
|
|
|
|
|
|||| |||| ||||
|
|
|
|
|
|||| |||| ||||
|
|
|
|
|
|||| |||| ||||
|
|
|
|
|
|||| |||| ||||
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:32:09 +02:00
|
|
|
|
[Mm][Xx]*)
|
|
|
|
|
read_ascii <<-EOF
|
|
|
|
|
${c7} \\\\ /
|
|
|
|
|
\\\\/
|
|
|
|
|
\\\\
|
|
|
|
|
/\\/ \\\\
|
|
|
|
|
/ \\ /\\
|
|
|
|
|
/ \\/ \\
|
|
|
|
|
/__________\\
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:06:14 +02:00
|
|
|
|
[Nn]et[Bb][Ss][Dd]*)
|
|
|
|
|
read_ascii 3 <<-EOF
|
|
|
|
|
${c7}\\\\${c3}\`-______,----__
|
|
|
|
|
${c7} \\\\ ${c3}__,---\`_
|
|
|
|
|
${c7} \\\\ ${c3}\`.____
|
|
|
|
|
${c7} \\\\${c3}-______,----\`-
|
|
|
|
|
${c7} \\\\
|
|
|
|
|
\\\\
|
|
|
|
|
\\\\
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 15:40:41 +02:00
|
|
|
|
[Nn]ix[Oo][Ss]*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 4 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c4} \\\\ \\\\ //
|
|
|
|
|
==\\\\__\\\\/ //
|
|
|
|
|
// \\\\//
|
|
|
|
|
==// //==
|
|
|
|
|
//\\\\___//
|
|
|
|
|
// /\\\\ \\\\==
|
|
|
|
|
// \\\\ \\\\
|
|
|
|
|
EOF
|
2019-09-24 15:40:41 +02:00
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 15:15:35 +02:00
|
|
|
|
[Oo]pen[Bb][Ss][Dd]*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 3 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c3} _____
|
|
|
|
|
\\- -/
|
|
|
|
|
\\_/ \\
|
|
|
|
|
| ${c7}O O${c3} |
|
|
|
|
|
|_ < ) 3 )
|
|
|
|
|
/ \\ /
|
|
|
|
|
/-_____-\\
|
|
|
|
|
EOF
|
2019-09-24 15:12:08 +02:00
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 20:58:54 +02:00
|
|
|
|
openSUSE*|open*SUSE*|[SUSE*|suse*)
|
|
|
|
|
read_ascii 2 <<-EOF
|
|
|
|
|
${c2} _______
|
|
|
|
|
__| __ \\
|
|
|
|
|
/ .\\ \\
|
|
|
|
|
\\__/ |
|
|
|
|
|
_______|
|
|
|
|
|
\\_______
|
|
|
|
|
__________/
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:27:07 +02:00
|
|
|
|
[Pp]arabola*)
|
|
|
|
|
read_ascii 5 <<-EOF
|
|
|
|
|
${c5} __ __ __ _
|
|
|
|
|
.\`_//_//_/ / \`.
|
|
|
|
|
/ .\`
|
|
|
|
|
/ .\`
|
|
|
|
|
/.\`
|
|
|
|
|
/\`
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:24:57 +02:00
|
|
|
|
[Pp]op!_[Oo][Ss]*)
|
|
|
|
|
read_ascii 6 <<-EOF
|
|
|
|
|
${c6}______
|
|
|
|
|
\\ _ \\ __
|
|
|
|
|
\\ \\ \\ \\ / /
|
|
|
|
|
\\ \\_\\ \\ / /
|
|
|
|
|
\\ ___\\ /_/
|
|
|
|
|
\\ \\ _
|
|
|
|
|
__\\_\\__(_)_
|
|
|
|
|
(___________)
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 21:21:34 +02:00
|
|
|
|
[Pp]ure[Oo][Ss]*)
|
2019-09-24 21:32:09 +02:00
|
|
|
|
read_ascii <<-EOF
|
2019-09-24 21:21:34 +02:00
|
|
|
|
${c7} _____________
|
|
|
|
|
| _________ |
|
|
|
|
|
| | | |
|
|
|
|
|
| | | |
|
|
|
|
|
| |_________| |
|
|
|
|
|
|_____________|
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
|
|
|
|
[Ss]lackware*)
|
|
|
|
|
read_ascii 4 <<-EOF
|
|
|
|
|
${c4} ________
|
|
|
|
|
/ ______|
|
|
|
|
|
| |______
|
|
|
|
|
\\______ \\
|
|
|
|
|
______| |
|
|
|
|
|
| |________/
|
|
|
|
|
|____________
|
|
|
|
|
EOF
|
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 15:40:41 +02:00
|
|
|
|
[Vv]oid*)
|
2019-09-24 17:48:03 +02:00
|
|
|
|
read_ascii 2 <<-EOF
|
2019-09-24 17:00:47 +02:00
|
|
|
|
${c2} _______
|
|
|
|
|
_ \\______ -
|
|
|
|
|
| \\ ___ \\ |
|
|
|
|
|
| | / \ | |
|
|
|
|
|
| | \___/ | |
|
|
|
|
|
| \\______ \\_|
|
|
|
|
|
-_______\\
|
|
|
|
|
EOF
|
2019-09-24 15:40:41 +02:00
|
|
|
|
;;
|
|
|
|
|
|
2019-09-24 15:06:10 +02:00
|
|
|
|
*)
|
2019-09-24 15:40:41 +02:00
|
|
|
|
# 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
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 15:06:10 +02:00
|
|
|
|
printf 'error: %s is not currently supported.\n' "$os"
|
|
|
|
|
printf 'error: Open an issue on GitHub for support to be added.\n'
|
|
|
|
|
exit 1
|
|
|
|
|
;;
|
2019-09-24 11:01:34 +02:00
|
|
|
|
esac
|
|
|
|
|
|
2019-09-24 13:33:15 +02:00
|
|
|
|
# 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
|
2019-09-24 17:56:03 +02:00
|
|
|
|
# information. The 'sed' is used to strip '[3Xm' color codes from
|
2019-09-24 13:33:15 +02:00
|
|
|
|
# the ascii art so they don't affect the width variable.
|
|
|
|
|
#
|
|
|
|
|
# The " " acts as the padding between the ascii art and the text as
|
|
|
|
|
# it appends 3 spaces to the end of each line.
|
2019-09-24 17:20:37 +02:00
|
|
|
|
while read -r line; do
|
2019-09-24 13:33:15 +02:00
|
|
|
|
ascii_height=$((ascii_height + 1))
|
|
|
|
|
ascii_width=$((${#line} > ascii_width ? ${#line} : ascii_width))
|
2019-09-24 13:59:14 +02:00
|
|
|
|
done <<-EOF
|
|
|
|
|
$(printf %s "$ascii" | sed 's/\[3.m//g')
|
|
|
|
|
EOF
|
2019-09-24 13:33:15 +02:00
|
|
|
|
|
|
|
|
|
# Add a gap between the ascii art and the information.
|
2019-09-24 17:20:37 +02:00
|
|
|
|
: $((ascii_width+=4))
|
2019-09-24 11:01:34 +02:00
|
|
|
|
|
|
|
|
|
# Print the ascii art and position the cursor back where we
|
|
|
|
|
# started prior to printing it.
|
2019-09-24 17:56:03 +02:00
|
|
|
|
# '[?7l': Disable line-wrapping.
|
|
|
|
|
# '[?25l': Hide the cursor.
|
|
|
|
|
# '[1m': Print the ascii in bold.
|
|
|
|
|
# '[m': Clear bold.
|
|
|
|
|
# '[%sA: Move the cursor up '$ascii_height' amount of lines.
|
|
|
|
|
printf '[?7l[?25l[1m%s[m[%sA' "$ascii" "$ascii_height"
|
2019-09-24 11:01:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 09:33:23 +02:00
|
|
|
|
main() {
|
2019-09-24 19:17:57 +02:00
|
|
|
|
# Leave the terminal how we found it on exit or Ctrl+C.
|
|
|
|
|
# '[?7h': Enable line-wrapping.
|
|
|
|
|
# '[?25h': Un-hide the cursor.
|
|
|
|
|
trap 'printf [?7h[?25h' EXIT INT
|
|
|
|
|
|
2019-09-24 11:26:34 +02:00
|
|
|
|
# Hide 'stderr' unless the first argument is '-v'. This saves
|
|
|
|
|
# polluting the script with '2>/dev/null'.
|
|
|
|
|
[ "$1" = -v ] || exec 2>/dev/null
|
|
|
|
|
|
2019-09-24 11:01:34 +02:00
|
|
|
|
# Generic color list.
|
|
|
|
|
# Disable warning about unused variables.
|
|
|
|
|
# shellcheck disable=2034
|
|
|
|
|
{
|
2019-09-24 12:27:33 +02:00
|
|
|
|
c1='[31m'; c2='[32m'
|
|
|
|
|
c3='[33m'; c4='[34m'
|
|
|
|
|
c5='[35m'; c6='[36m'
|
|
|
|
|
c7='[37m'; c8='[38m'
|
2019-09-24 11:01:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-24 09:33:23 +02:00
|
|
|
|
# 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.
|
2019-09-24 13:59:14 +02:00
|
|
|
|
read -r os kernel <<-EOF
|
|
|
|
|
$(uname -sr)
|
|
|
|
|
EOF
|
2019-09-24 09:33:23 +02:00
|
|
|
|
|
2019-09-24 17:48:03 +02:00
|
|
|
|
# Always run 'get_os' for the purposes of detecting which ascii
|
2019-09-24 15:40:41 +02:00
|
|
|
|
# art to display.
|
2019-09-24 17:48:03 +02:00
|
|
|
|
get_os
|
2019-09-24 15:40:41 +02:00
|
|
|
|
|
2019-09-24 13:04:43 +02:00
|
|
|
|
# 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
|
2019-09-24 17:48:03 +02:00
|
|
|
|
set +f ${PF_INFO-ascii title os host kernel uptime pkgs memory}
|
2019-09-24 13:41:20 +02:00
|
|
|
|
|
|
|
|
|
# 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
|
2019-09-24 14:11:55 +02:00
|
|
|
|
command -v "get_$info" >/dev/null &&
|
2019-09-24 13:55:52 +02:00
|
|
|
|
info_length=$((${#info} > info_length ? ${#info} : info_length))
|
2019-09-24 13:41:20 +02:00
|
|
|
|
done
|
2019-09-24 13:04:43 +02:00
|
|
|
|
|
2019-09-24 17:53:33 +02:00
|
|
|
|
# Add an additional space of length to act as a gap.
|
|
|
|
|
: $((info_length+=1))
|
|
|
|
|
|
2019-09-24 13:04:43 +02:00
|
|
|
|
# Iterate over the above list and run any existing "get_" functions.
|
2019-09-24 20:12:31 +02:00
|
|
|
|
for info; do "get_$info"; done
|
2019-09-24 13:04:43 +02:00
|
|
|
|
}
|
2019-09-24 11:01:34 +02:00
|
|
|
|
|
2019-09-24 12:32:06 +02:00
|
|
|
|
# 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, else move it down N lines.
|
2019-09-24 19:17:57 +02:00
|
|
|
|
cursor_pos=$((info_height > ascii_height ? 0 : ascii_height - info_height))
|
|
|
|
|
|
|
|
|
|
# Print '$cursor_pos' amount of newlines. Using cursor down doesn't scroll
|
|
|
|
|
# the screen correctly if this causes the cursor to hit the bottom of the
|
|
|
|
|
# window. Using '0' gives us an extra iteration, adding a bottom line gap.
|
|
|
|
|
printf '%0.s\n' $(seq 0 "$cursor_pos")
|
2019-09-24 09:33:23 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
main "$@"
|