Compare Pastes
Differences between the pastes
#273175 (11.03.2024 13:27)
and
#274603 (23.05.2024 02:13).
| 1 | #!/bin/sh | |
| 2 | # | |
| 3 | # pfetch - Simple POSIX sh fetch script. | |
| 4 | ||
| 5 | # Wrapper around all escape sequences used by pfetch to allow for | |
| 6 | # greater control over which sequences are used (if any at all). | |
| 7 | esc() {
| |
| 8 | case $1 in | |
| 9 | CUU) e="${esc_c}[${2}A" ;; # cursor up
| |
| 10 | CUD) e="${esc_c}[${2}B" ;; # cursor down
| |
| 11 | CUF) e="${esc_c}[${2}C" ;; # cursor right
| |
| 12 | CUB) e="${esc_c}[${2}D" ;; # cursor left
| |
| 13 | ||
| 14 | # text formatting | |
| 15 | SGR) | |
| 16 | case ${PF_COLOR:=1} in
| |
| 17 | (1) | |
| 18 | e="${esc_c}[${2}m"
| |
| 19 | ;; | |
| 20 | ||
| 21 | (0) | |
| 22 | # colors disabled | |
| 23 | e= | |
| 24 | ;; | |
| 25 | esac | |
| 26 | ;; | |
| 27 | ||
| 28 | # line wrap | |
| 29 | DECAWM) | |
| 30 | case $TERM in | |
| 31 | (dumb | minix | cons25) | |
| 32 | # not supported | |
| 33 | e= | |
| 34 | ;; | |
| 35 | ||
| 36 | (*) | |
| 37 | e="${esc_c}[?7${2}"
| |
| 38 | ;; | |
| 39 | esac | |
| 40 | ;; | |
| 41 | esac | |
| 42 | } | |
| 43 | ||
| 44 | # Print a sequence to the terminal. | |
| 45 | esc_p() {
| |
| 46 | esc "$@" | |
| 47 | printf '%s' "$e" | |
| 48 | } | |
| 49 | ||
| 50 | # This is just a simple wrapper around 'command -v' to avoid | |
| 51 | # spamming '>/dev/null' throughout this function. This also guards | |
| 52 | # against aliases and functions. | |
| 53 | has() {
| |
| 54 | _cmd=$(command -v "$1") 2>/dev/null || return 1 | |
| 55 | [ -x "$_cmd" ] || return 1 | |
| 56 | } | |
| 57 | ||
| 58 | log() {
| |
| 59 | # The 'log()' function handles the printing of information. | |
| 60 | # In 'pfetch' (and 'neofetch'!) the printing of the ascii art and info | |
| 61 | # happen independently of each other. | |
| 62 | # | |
| 63 | # The size of the ascii art is stored and the ascii is printed first. | |
| 64 | # Once the ascii is printed, the cursor is located right below the art | |
| 65 | # (See marker $[1]). | |
| 66 | # | |
| 67 | # Using the stored ascii size, the cursor is then moved to marker $[2]. | |
| 68 | # This is simply a cursor up escape sequence using the "height" of the | |
| 69 | # ascii art. | |
| 70 | # | |
| 71 | # 'log()' then moves the cursor to the right the "width" of the ascii art | |
| 72 | # with an additional amount of padding to add a gap between the art and | |
| 73 | # the information (See marker $[3]). | |
| 74 | # | |
| 75 | # When 'log()' has executed, the cursor is then located at marker $[4]. | |
| 76 | # When 'log()' is run a second time, the next line of information is | |
| 77 | # printed, moving the cursor to marker $[5]. | |
| 78 | # | |
| 79 | # Markers $[4] and $[5] repeat all the way down through the ascii art | |
| 80 | # until there is no more information left to print. | |
| 81 | # | |
| 82 | # Every time 'log()' is called the script keeps track of how many lines | |
| 83 | # were printed. When printing is complete the cursor is then manually | |
| 84 | # placed below the information and the art according to the "heights" | |
| 85 | # of both. | |
| 86 | # | |
| 87 | # The math is simple: move cursor down $((ascii_height - info_height)). | |
| 88 | # If the aim is to move the cursor from marker $[5] to marker $[6], | |
| 89 | # plus the ascii height is 8 while the info height is 2 it'd be a move | |
| 90 | # of 6 lines downwards. | |
| 91 | # | |
| 92 | # However, if the information printed is "taller" (takes up more lines) | |
| 93 | # than the ascii art, the cursor isn't moved at all! | |
| 94 | # | |
| 95 | # Once the cursor is at marker $[6], the script exits. This is the gist | |
| 96 | # of how this "dynamic" printing and layout works. | |
| 97 | # | |
| 98 | # This method allows ascii art to be stored without markers for info | |
| 99 | # and it allows for easy swapping of info order and amount. | |
| 100 | # | |
| 101 | # $[2] ___ $[3] goldie@KISS | |
| 102 | # $[4](.· | $[5] os KISS Linux | |
| 103 | # (<> | | |
| 104 | # / __ \ | |
| 105 | # ( / \ /| | |
| 106 | # _/\ __)/_) | |
| 107 | # \/-____\/ | |
| 108 | # $[1] | |
| 109 | # | |
| 110 | # $[6] /home/goldie $ | |
| 111 | ||
| 112 | # End here if no data was found. | |
| 113 | [ "$2" ] || return | |
| 114 | ||
| 115 | # Store the values of '$1' and '$3' as we reset the argument list below. | |
| 116 | name=$1 | |
| 117 | use_seperator=$3 | |
| 118 | ||
| 119 | # Use 'set --' as a means of stripping all leading and trailing | |
| 120 | # white-space from the info string. This also normalizes all | |
| 121 | # white-space inside of the string. | |
| 122 | # | |
| 123 | # Disable the shellcheck warning for word-splitting | |
| 124 | # as it's safe and intended ('set -f' disables globbing).
| |
| 125 | # shellcheck disable=2046,2086 | |
| 126 | {
| |
| 127 | set -f | |
| 128 | set +f -- $2 | |
| 129 | info=$* | |
| 130 | } | |
| 131 | ||
| 132 | # Move the cursor to the right, the width of the ascii art with an | |
| 133 | # additional gap for text spacing. | |
| 134 | esc_p CUF "$ascii_width" | |
| 135 | ||
| 136 | # Print the info name and color the text. | |
| 137 | esc_p SGR "3${PF_COL1-4}";
| |
| 138 | esc_p SGR 1 | |
| 139 | printf '%s' "$name" | |
| 140 | esc_p SGR 0 | |
| 141 | ||
| 142 | # Print the info name and info data separator, if applicable. | |
| 143 | [ "$use_seperator" ] || printf %s "$PF_SEP" | |
| 144 | ||
| 145 | # Move the cursor backward the length of the *current* info name and | |
| 146 | # then move it forwards the length of the *longest* info name. This | |
| 147 | # aligns each info data line. | |
| 148 | esc_p CUB "${#name}"
| |
| 149 | esc_p CUF "${PF_ALIGN:-$info_length}"
| |
| 150 | ||
| 151 | # Print the info data, color it and strip all leading whitespace | |
| 152 | # from the string. | |
| 153 | esc_p SGR "3${PF_COL2-9}"
| |
| 154 | printf '%s' "$info" | |
| 155 | esc_p SGR 0 | |
| 156 | printf '\n' | |
| 157 | ||
| 158 | # Keep track of the number of times 'log()' has been run. | |
| 159 | info_height=$((${info_height:-0} + 1))
| |
| 160 | } | |
| 161 | ||
| 162 | get_title() {
| |
| 163 | # Username is retrieved by first checking '$USER' with a fallback | |
| 164 | # to the 'id -un' command. | |
| 165 | user=${USER:-$(id -un)}
| |
| 166 | ||
| 167 | # Hostname is retrieved by first checking '$HOSTNAME' with a fallback | |
| 168 | # to the 'hostname' command. | |
| 169 | # | |
| 170 | # Disable the warning about '$HOSTNAME' being undefined in POSIX sh as | |
| 171 | # the intention for using it is allowing the user to overwrite the | |
| 172 | # value on invocation. | |
| 173 | # shellcheck disable=3028,2039 | |
| 174 | hostname=${HOSTNAME:-${hostname:-$(hostname)}}
| |
| 175 | ||
| 176 | # If the hostname is still not found, fallback to the contents of the | |
| 177 | # /etc/hostname file. | |
| 178 | [ "$hostname" ] || read -r hostname < /etc/hostname | |
| 179 | ||
| 180 | # Add escape sequences for coloring to user and host name. As we embed | |
| 181 | # them directly in the arguments passed to log(), we cannot use esc_p(). | |
| 182 | esc SGR 1 | |
| 183 | user=$e$user | |
| 184 | esc SGR "3${PF_COL3:-1}"
| |
| 185 | user=$e$user | |
| 186 | esc SGR 1 | |
| 187 | user=$user$e | |
| 188 | esc SGR 1 | |
| 189 | hostname=$e$hostname | |
| 190 | esc SGR "3${PF_COL3:-1}"
| |
| 191 | hostname=$e$hostname | |
| 192 | ||
| 193 | log "${user}@${hostname}" " " " " >&6
| |
| 194 | } | |
| 195 | ||
| 196 | get_os() {
| |
| 197 | # This function is called twice, once to detect the distribution name | |
| 198 | # for the purposes of picking an ascii art early and secondly to display | |
| 199 | # the distribution name in the info output (if enabled). | |
| 200 | # | |
| 201 | # On first run, this function displays _nothing_, only on the second | |
| 202 | # invocation is 'log()' called. | |
| 203 | [ "$distro" ] && {
| |
| 204 | log os "$distro" >&6 | |
| 205 | return | |
| 206 | } | |
| 207 | ||
| 208 | case $os in | |
| 209 | (Linux*) | |
| 210 | # Some Linux distributions (which are based on others) | |
| 211 | # fail to identify as they **do not** change the upstream | |
| 212 | # distribution's identification packages or files. | |
| 213 | # | |
| 214 | # It is senseless to add a special case in the code for | |
| 215 | # each and every distribution (which _is_ technically no | |
| 216 | # different from what it is based on) as they're either too | |
| 217 | # lazy to modify upstream's identification files or they | |
| 218 | # don't have the know-how (or means) to ship their own | |
| 219 | # lsb-release package. | |
| 220 | # | |
| 221 | # This causes users to think there's a bug in system detection | |
| 222 | # tools like neofetch or pfetch when they technically *do* | |
| 223 | # function correctly. | |
| 224 | # | |
| 225 | # Exceptions are made for distributions which are independent, | |
| 226 | # not based on another distribution or follow different | |
| 227 | # standards. | |
| 228 | # | |
| 229 | # This applies only to distributions which follow the standard | |
| 230 | # by shipping unmodified identification files and packages | |
| 231 | # from their respective upstreams. | |
| 232 | if has lsb_release; then | |
| 233 | distro=$(lsb_release -sd) | |
| 234 | ||
| 235 | # Android detection works by checking for the existence of | |
| 236 | # the follow two directories. I don't think there's a simpler | |
| 237 | # method than this. | |
| 238 | elif [ -d /system/app ] && [ -d /system/priv-app ]; then | |
| 239 | distro="Android $(getprop ro.build.version.release)" | |
| 240 | ||
| 241 | elif [ -f /etc/os-release ]; then | |
| 242 | # This used to be a simple '. /etc/os-release' but I believe | |
| 243 | # this is insecure as we blindly executed whatever was in the | |
| 244 | # file. This parser instead simply handles 'key=val', treating | |
| 245 | # the file contents as plain-text. | |
| 246 | while IFS='=' read -r key val; do | |
| 247 | case $key in | |
| 248 | (PRETTY_NAME) | |
| 249 | distro=$val | |
| 250 | ;; | |
| 251 | esac | |
| 252 | done < /etc/os-release | |
| 253 | ||
| 254 | else | |
| 255 | # Special cases for (independent) distributions which | |
| 256 | # don't follow any os-release/lsb standards whatsoever. | |
| 257 | has crux && distro=$(crux) | |
| 258 | has guix && distro='Guix System' | |
| 259 | fi | |
| 260 | ||
| 261 | # 'os-release' and 'lsb_release' sometimes add quotes | |
| 262 | # around the distribution name, strip them. | |
| 263 | distro=${distro##[\"\']}
| |
| 264 | distro=${distro%%[\"\']}
| |
| 265 | ||
| 266 | # Check to see if we're running Bedrock Linux which is | |
| 267 | # very unique. This simply checks to see if the user's | |
| 268 | # PATH contains a Bedrock specific value. | |
| 269 | case $PATH in | |
| 270 | (*/bedrock/cross/*) | |
| 271 | distro='Bedrock Linux' | |
| 272 | ;; | |
| 273 | esac | |
| 274 | ||
| 275 | # Check to see if Linux is running in Windows 10 under | |
| 276 | # WSL1 (Windows subsystem for Linux [version 1]) and | |
| 277 | # append a string accordingly. | |
| 278 | # | |
| 279 | # If the kernel version string ends in "-Microsoft", | |
| 280 | # we're very likely running under Windows 10 in WSL1. | |
| 281 | if [ "$WSLENV" ]; then | |
| 282 | distro="${distro}${WSLENV+ on Windows 10 [WSL2]}"
| |
| 283 | ||
| 284 | # Check to see if Linux is running in Windows 10 under | |
| 285 | # WSL2 (Windows subsystem for Linux [version 2]) and | |
| 286 | # append a string accordingly. | |
| 287 | # | |
| 288 | # This checks to see if '$WSLENV' is defined. This | |
| 289 | # appends the Windows 10 string even if '$WSLENV' is | |
| 290 | # empty. We only need to check that is has been _exported_. | |
| 291 | elif [ -z "${kernel%%*-Microsoft}" ]; then
| |
| 292 | distro="$distro on Windows 10 [WSL1]" | |
| 293 | fi | |
| 294 | ;; | |
| 295 | ||
| 296 | (Darwin*) | |
| 297 | # Parse the SystemVersion.plist file to grab the macOS | |
| 298 | # version. The file is in the following format: | |
| 299 | # | |
| 300 | # | |
| 301 | # | |
| 302 | # | |
| 303 | # 'IFS' is set to '<>' to enable splitting between the | |
| 304 | # keys and a second 'read' is used to operate on the | |
| 305 | # next line directly after a match. | |
| 306 | # | |
| 307 | # '_' is used to nullify a field. '_ _ line _' basically | |
| 308 | # says "populate $line with the third field's contents". | |
| 309 | while IFS='<>' read -r _ _ line _; do | |
| 310 | case $line in | |
| 311 | # Match 'ProductVersion' and read the next line | |
| 312 | # directly as it contains the key's value. | |
| 313 | ProductVersion) | |
| 314 | IFS='<>' read -r _ _ mac_version _ | |
| 315 | continue | |
| 316 | ;; | |
| 317 | ||
| 318 | ProductName) | |
| 319 | IFS='<>' read -r _ _ mac_product _ | |
| 320 | continue | |
| 321 | ;; | |
| 322 | esac | |
| 323 | done < /System/Library/CoreServices/SystemVersion.plist | |
| 324 | ||
| 325 | # Use the ProductVersion to determine which macOS/OS X codename | |
| 326 | # the system has. As far as I'm aware there's no "dynamic" way | |
| 327 | # of grabbing this information. | |
| 328 | case $mac_version in | |
| 329 | (10.4*) distro='Mac OS X Tiger' ;; | |
| 330 | (10.5*) distro='Mac OS X Leopard' ;; | |
| 331 | (10.6*) distro='Mac OS X Snow Leopard' ;; | |
| 332 | (10.7*) distro='Mac OS X Lion' ;; | |
| 333 | (10.8*) distro='OS X Mountain Lion' ;; | |
| 334 | (10.9*) distro='OS X Mavericks' ;; | |
| 335 | (10.10*) distro='OS X Yosemite' ;; | |
| 336 | (10.11*) distro='OS X El Capitan' ;; | |
| 337 | (10.12*) distro='macOS Sierra' ;; | |
| 338 | (10.13*) distro='macOS High Sierra' ;; | |
| 339 | (10.14*) distro='macOS Mojave' ;; | |
| 340 | (10.15*) distro='macOS Catalina' ;; | |
| 341 | (11*) distro='macOS Big Sur' ;; | |
| 342 | (12*) distro='macOS Monterey' ;; | |
| 343 | (*) distro='macOS' ;; | |
| 344 | esac | |
| 345 | ||
| 346 | # Use the ProductName to determine if we're running in iOS. | |
| 347 | case $mac_product in | |
| 348 | (iP*) distro='iOS' ;; | |
| 349 | esac | |
| 350 | ||
| 351 | distro="$distro $mac_version" | |
| 352 | ;; | |
| 353 | ||
| 354 | (Haiku) | |
| 355 | # Haiku uses 'uname -v' for version information | |
| 356 | # instead of 'uname -r' which only prints '1'. | |
| 357 | distro=$(uname -sv) | |
| 358 | ;; | |
| 359 | ||
| 360 | (Minix|DragonFly) | |
| 361 | distro="$os $kernel" | |
| 362 | ||
| 363 | # Minix and DragonFly don't support the escape | |
| 364 | # sequences used, clear the exit trap. | |
| 365 | trap '' EXIT | |
| 366 | ;; | |
| 367 | ||
| 368 | (SunOS) | |
| 369 | # Grab the first line of the '/etc/release' file | |
| 370 | # discarding everything after '('.
| |
| 371 | IFS='(' read -r distro _ < /etc/release
| |
| 372 | ;; | |
| 373 | ||
| 374 | (OpenBSD*) | |
| 375 | # Show the OpenBSD version type (current if present). | |
| 376 | # kern.version=OpenBSD 6.6-current (GENERIC.MP) ... | |
| 377 | IFS=' =' read -r _ distro openbsd_ver _ <<-EOF | |
| 378 | $(sysctl kern.version) | |
| 379 | EOF | |
| 380 | ||
| 381 | distro="$distro $openbsd_ver" | |
| 382 | ;; | |
| 383 | ||
| 384 | (FreeBSD) | |
| 385 | distro="$os $(freebsd-version)" | |
| 386 | ;; | |
| 387 | ||
| 388 | (*) | |
| 389 | # Catch all to ensure '$distro' is never blank. | |
| 390 | # This also handles the BSDs. | |
| 391 | distro="$os $kernel" | |
| 392 | ;; | |
| 393 | esac | |
| 394 | } | |
| 395 | ||
| 396 | get_kernel() {
| |
| 397 | case $os in | |
| 398 | # Don't print kernel output on some systems as the | |
| 399 | # OS name includes it. | |
| 400 | (*BSD*|Haiku|Minix) | |
| 401 | return | |
| 402 | ;; | |
| 403 | esac | |
| 404 | ||
| 405 | # '$kernel' is the cached output of 'uname -r'. | |
| 406 | log kernel "$kernel" >&6 | |
| 407 | } | |
| 408 | ||
| 409 | get_host() {
| |
| 410 | case $os in | |
| 411 | (Linux*) | |
| 412 | # Despite what these files are called, version doesn't | |
| 413 | # always contain the version nor does name always contain | |
| 414 | # the name. | |
| 415 | read -r name < /sys/devices/virtual/dmi/id/product_name | |
| 416 | read -r version < /sys/devices/virtual/dmi/id/product_version | |
| 417 | read -r model < /sys/firmware/devicetree/base/model | |
| 418 | ||
| 419 | host="$name $version $model" | |
| 420 | ;; | |
| 421 | ||
| 422 | (Darwin* | FreeBSD* | DragonFly*) | |
| 423 | host=$(sysctl -n hw.model) | |
| 424 | ;; | |
| 425 | ||
| 426 | (NetBSD*) | |
| 427 | host=$(sysctl -n machdep.dmi.system-vendor \ | |
| 428 | machdep.dmi.system-product) | |
| 429 | ;; | |
| 430 | ||
| 431 | (OpenBSD*) | |
| 432 | host=$(sysctl -n hw.version) | |
| 433 | ;; | |
| 434 | ||
| 435 | (*BSD* | Minix) | |
| 436 | host=$(sysctl -n hw.vendor hw.product) | |
| 437 | ;; | |
| 438 | esac | |
| 439 | ||
| 440 | # Turn the host string into an argument list so we can iterate | |
| 441 | # over it and remove OEM strings and other information which | |
| 442 | # shouldn't be displayed. | |
| 443 | # | |
| 444 | # Disable the shellcheck warning for word-splitting | |
| 445 | # as it's safe and intended ('set -f' disables globbing).
| |
| 446 | # shellcheck disable=2046,2086 | |
| 447 | {
| |
| 448 | set -f | |
| 449 | set +f -- $host | |
| 450 | host= | |
| 451 | } | |
| 452 | ||
| 453 | # Iterate over the host string word by word as a means of stripping | |
| 454 | # unwanted and OEM information from the string as a whole. | |
| 455 | # | |
| 456 | # This could have been implemented using a long 'sed' command with | |
| 457 | # a list of word replacements, however I want to show that something | |
| 458 | # like this is possible in pure sh. | |
| 459 | # | |
| 460 | # This string reconstruction is needed as some OEMs either leave the | |
| 461 | # identification information as "To be filled by OEM", "Default", | |
| 462 | # "undefined" etc and we shouldn't print this to the screen. | |
| 463 | for word do | |
| 464 | # This works by reconstructing the string by excluding words | |
| 465 | # found in the "blacklist" below. Only non-matches are appended | |
| 466 | # to the final host string. | |
| 467 | case $word in | |
| 468 | (To | [Bb]e | [Ff]illed | [Bb]y | O.E.M. | OEM |\ | |
| 469 | Not | Applicable | Specified | System | Product | Name |\ | |
| 470 | Version | Undefined | Default | string | INVALID | � | os |\ | |
| 471 | Type1ProductConfigId ) | |
| 472 | continue | |
| 473 | ;; | |
| 474 | esac | |
| 475 | ||
| 476 | host="$host$word " | |
| 477 | done | |
| 478 | ||
| 479 | # '$arch' is the cached output from 'uname -m'. | |
| 480 | log host "${host:-$arch}" >&6
| |
| 481 | } | |
| 482 | ||
| 483 | get_uptime() {
| |
| 484 | # Uptime works by retrieving the data in total seconds and then | |
| 485 | # converting that data into days, hours and minutes using simple | |
| 486 | # math. | |
| 487 | case $os in | |
| 488 | (Linux* | Minix* | SerenityOS*) | |
| 489 | IFS=. read -r s _ < /proc/uptime | |
| 490 | ;; | |
| 491 | ||
| 492 | (Darwin* | *BSD* | DragonFly*) | |
| 493 | s=$(sysctl -n kern.boottime) | |
| 494 | ||
| 495 | # Extract the uptime in seconds from the following output: | |
| 496 | # [...] { sec = 1271934886, usec = 667779 } Thu Apr 22 12:14:46 2010
| |
| 497 | s=${s#*=}
| |
| 498 | s=${s%,*}
| |
| 499 | ||
| 500 | # The uptime format from 'sysctl' needs to be subtracted from | |
| 501 | # the current time in seconds. | |
| 502 | s=$(($(date +%s) - s)) | |
| 503 | ;; | |
| 504 | ||
| 505 | (Haiku) | |
| 506 | # The boot time is returned in microseconds, convert it to | |
| 507 | # regular seconds. | |
| 508 | s=$(($(system_time) / 1000000)) | |
| 509 | ;; | |
| 510 | ||
| 511 | (SunOS) | |
| 512 | # Split the output of 'kstat' on '.' and any white-space | |
| 513 | # which exists in the command output. | |
| 514 | # | |
| 515 | # The output is as follows: | |
| 516 | # unix:0:system_misc:snaptime 14809.906993005 | |
| 517 | # | |
| 518 | # The parser extracts: ^^^^^ | |
| 519 | IFS=' .' read -r _ s _ <<-EOF | |
| 520 | $(kstat -p unix:0:system_misc:snaptime) | |
| 521 | EOF | |
| 522 | ;; | |
| 523 | ||
| 524 | (IRIX) | |
| 525 | # Grab the uptime in a pretty format. Usually, | |
| 526 | # 00:00:00 from the 'ps' command. | |
| 527 | t=$(LC_ALL=POSIX ps -o etime= -p 1) | |
| 528 | ||
| 529 | # Split the pretty output into days or hours | |
| 530 | # based on the uptime. | |
| 531 | case $t in | |
| 532 | (*-*) d=${t%%-*} t=${t#*-} ;;
| |
| 533 | (*:*:*) h=${t%%:*} t=${t#*:} ;;
| |
| 534 | esac | |
| 535 | ||
| 536 | h=${h#0} t=${t#0}
| |
| 537 | ||
| 538 | # Convert the split pretty fields back into | |
| 539 | # seconds so we may re-convert them to our format. | |
| 540 | s=$((${d:-0}*86400 + ${h:-0}*3600 + ${t%%:*}*60 + ${t#*:}))
| |
| 541 | ;; | |
| 542 | esac | |
| 543 | ||
| 544 | # Convert the uptime from seconds into days, hours and minutes. | |
| 545 | d=$((s / 60 / 60 / 24)) | |
| 546 | h=$((s / 60 / 60 % 24)) | |
| 547 | m=$((s / 60 % 60)) | |
| 548 | ||
| 549 | # Only append days, hours and minutes if they're non-zero. | |
| 550 | case "$d" in ([!0]*) uptime="${uptime}${d}d "; esac
| |
| 551 | case "$h" in ([!0]*) uptime="${uptime}${h}h "; esac
| |
| 552 | case "$m" in ([!0]*) uptime="${uptime}${m}m "; esac
| |
| 553 | ||
| 554 | log uptime "${uptime:-0m}" >&6
| |
| 555 | } | |
| 556 | ||
| 557 | get_pkgs() {
| |
| 558 | # This works by first checking for which package managers are | |
| 559 | # installed and finally by printing each package manager's | |
| 560 | # package list with each package one per line. | |
| 561 | # | |
| 562 | # The output from this is then piped to 'wc -l' to count each | |
| 563 | # line, giving us the total package count of whatever package | |
| 564 | # managers are installed. | |
| 565 | packages=$( | |
| 566 | case $os in | |
| 567 | (Linux*) | |
| 568 | # Commands which print packages one per line. | |
| 569 | has bonsai && bonsai list | |
| 570 | has crux && pkginfo -i | |
| 571 | has pacman-key && pacman -Qq | |
| 572 | has dpkg && dpkg-query -f '.\n' -W | |
| 573 | has rpm && rpm -qa | |
| 574 | has xbps-query && xbps-query -l | |
| 575 | has apk && apk info | |
| 576 | has guix && guix package --list-installed | |
| 577 | has opkg && opkg list-installed | |
| 578 | ||
| 579 | # Directories containing packages. | |
| 580 | has kiss && printf '%s\n' /var/db/kiss/installed/*/ | |
| 581 | has cpt-list && printf '%s\n' /var/db/cpt/installed/*/ | |
| 582 | has brew && printf '%s\n' "$(brew --cellar)/"* | |
| 583 | has emerge && printf '%s\n' /var/db/pkg/*/*/ | |
| 584 | has pkgtool && printf '%s\n' /var/log/packages/* | |
| 585 | has eopkg && printf '%s\n' /var/lib/eopkg/package/* | |
| 586 | ||
| 587 | # 'nix' requires two commands. | |
| 588 | has nix-store && {
| |
| 589 | nix-store -q --requisites /run/current-system/sw | |
| 590 | nix-store -q --requisites ~/.nix-profile | |
| 591 | } | |
| 592 | ;; | |
| 593 | ||
| 594 | (Darwin*) | |
| 595 | # Commands which print packages one per line. | |
| 596 | has pkgin && pkgin list | |
| 597 | has dpkg && dpkg-query -f '.\n' -W | |
| 598 | ||
| 599 | # Directories containing packages. | |
| 600 | has brew && printf '%s\n' /usr/local/Cellar/* | |
| 601 | ||
| 602 | # 'port' prints a single line of output to 'stdout' | |
| 603 | # when no packages are installed and exits with | |
| 604 | # success causing a false-positive of 1 package | |
| 605 | # installed. | |
| 606 | # | |
| 607 | # 'port' should really exit with a non-zero code | |
| 608 | # in this case to allow scripts to cleanly handle | |
| 609 | # this behavior. | |
| 610 | has port && {
| |
| 611 | pkg_list=$(port installed) | |
| 612 | ||
| 613 | case "$pkg_list" in | |
| 614 | ("No ports are installed.")
| |
| 615 | # do nothing | |
| 616 | ;; | |
| 617 | ||
| 618 | (*) | |
| 619 | printf '%s\n' "$pkg_list" | |
| 620 | ;; | |
| 621 | esac | |
| 622 | } | |
| 623 | ;; | |
| 624 | ||
| 625 | (FreeBSD*|DragonFly*) | |
| 626 | pkg info | |
| 627 | ;; | |
| 628 | ||
| 629 | (OpenBSD*) | |
| 630 | printf '%s\n' /var/db/pkg/*/ | |
| 631 | ;; | |
| 632 | ||
| 633 | (NetBSD*) | |
| 634 | pkg_info | |
| 635 | ;; | |
| 636 | ||
| 637 | (Haiku) | |
| 638 | printf '%s\n' /boot/system/package-links/* | |
| 639 | ;; | |
| 640 | ||
| 641 | (Minix) | |
| 642 | printf '%s\n' /usr/pkg/var/db/pkg/*/ | |
| 643 | ;; | |
| 644 | ||
| 645 | (SunOS) | |
| 646 | has pkginfo && pkginfo -i | |
| 647 | has pkg && pkg list | |
| 648 | ;; | |
| 649 | ||
| 650 | (IRIX) | |
| 651 | versions -b | |
| 652 | ;; | |
| 653 | ||
| 654 | (SerenityOS) | |
| 655 | while IFS=" " read -r type _; do | |
| 656 | [ "$type" != dependency ] && | |
| 657 | printf "\n" | |
| 658 | done < /usr/Ports/packages.db | |
| 659 | ;; | |
| 660 | esac | wc -l | |
| 661 | ) | |
| 662 | ||
| 663 | # 'wc -l' can have leading and/or trailing whitespace | |
| 664 | # depending on the implementation, so strip them. | |
| 665 | # Procedure explained at https://github.com/dylanaraps/pure-sh-bible | |
| 666 | # (trim-leading-and-trailing-white-space-from-string) | |
| 667 | packages=${packages#"${packages%%[![:space:]]*}"}
| |
| 668 | packages=${packages%"${packages##*[![:space:]]}"}
| |
| 669 | ||
| 670 | case $os in | |
| 671 | # IRIX's package manager adds 3 lines of extra | |
| 672 | # output which we must account for here. | |
| 673 | (IRIX) | |
| 674 | packages=$((packages - 3)) | |
| 675 | ;; | |
| 676 | ||
| 677 | # OpenBSD's wc prints whitespace before the output | |
| 678 | # which needs to be stripped. | |
| 679 | (OpenBSD) | |
| 680 | packages=$((packages)) | |
| 681 | ;; | |
| 682 | esac | |
| 683 | ||
| 684 | case $packages in | |
| 685 | (1?*|[2-9]*) | |
| 686 | log pkgs "$packages" >&6 | |
| 687 | ;; | |
| 688 | esac | |
| 689 | } | |
| 690 | ||
| 691 | get_memory() {
| |
| 692 | case $os in | |
| 693 | # Used memory is calculated using the following "formula": | |
| 694 | # MemUsed = MemTotal + Shmem - MemFree - Buffers - Cached - SReclaimable | |
| 695 | # Source: https://github.com/KittyKatt/screenFetch/issues/386 | |
| 696 | (Linux*) | |
| 697 | # Parse the '/proc/meminfo' file splitting on ':' and 'k'. | |
| 698 | # The format of the file is 'key: 000kB' and an additional | |
| 699 | # split is used on 'k' to filter out 'kB'. | |
| 700 | while IFS=':k ' read -r key val _; do | |
| 701 | case $key in | |
| 702 | (MemTotal) | |
| 703 | mem_used=$((mem_used + val)) | |
| 704 | mem_full=$val | |
| 705 | ;; | |
| 706 | ||
| 707 | (Shmem) | |
| 708 | mem_used=$((mem_used + val)) | |
| 709 | ;; | |
| 710 | ||
| 711 | (MemFree | Buffers | Cached | SReclaimable) | |
| 712 | mem_used=$((mem_used - val)) | |
| 713 | ;; | |
| 714 | ||
| 715 | # If detected this will be used over the above calculation | |
| 716 | # for mem_used. Available since Linux 3.14rc. | |
| 717 | # See kernel commit 34e431b0ae398fc54ea69ff85ec700722c9da773 | |
| 718 | (MemAvailable) | |
| 719 | mem_avail=$val | |
| 720 | ;; | |
| 721 | esac | |
| 722 | done < /proc/meminfo | |
| 723 | ||
| 724 | case $mem_avail in | |
| 725 | (*[0-9]*) | |
| 726 | mem_used=$(((mem_full - mem_avail) / 1024)) | |
| 727 | ;; | |
| 728 | ||
| 729 | *) | |
| 730 | mem_used=$((mem_used / 1024)) | |
| 731 | ;; | |
| 732 | esac | |
| 733 | ||
| 734 | mem_full=$((mem_full / 1024)) | |
| 735 | ;; | |
| 736 | ||
| 737 | # Used memory is calculated using the following "formula": | |
| 738 | # (wired + active + occupied) * 4 / 1024 | |
| 739 | (Darwin*) | |
| 740 | mem_full=$(($(sysctl -n hw.memsize) / 1024 / 1024)) | |
| 741 | ||
| 742 | # Parse the 'vmstat' file splitting on ':' and '.'. | |
| 743 | # The format of the file is 'key: 000.' and an additional | |
| 744 | # split is used on '.' to filter it out. | |
| 745 | while IFS=:. read -r key val; do | |
| 746 | case $key in | |
| 747 | (*' wired'*|*' active'*|*' occupied'*) | |
| 748 | mem_used=$((mem_used + ${val:-0}))
| |
| 749 | ;; | |
| 750 | esac | |
| 751 | ||
| 752 | # Using '<<-EOF' is the only way to loop over a command's | |
| 753 | # output without the use of a pipe ('|').
| |
| 754 | # This ensures that any variables defined in the while loop | |
| 755 | # are still accessible in the script. | |
| 756 | done <<-EOF | |
| 757 | $(vm_stat) | |
| 758 | EOF | |
| 759 | ||
| 760 | mem_used=$((mem_used * 4 / 1024)) | |
| 761 | ;; | |
| 762 | ||
| 763 | (OpenBSD*) | |
| 764 | mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024)) | |
| 765 | ||
| 766 | # This is a really simpler parser for 'vmstat' which grabs | |
| 767 | # the used memory amount in a lazy way. 'vmstat' prints 3 | |
| 768 | # lines of output with the needed value being stored in the | |
| 769 | # final line. | |
| 770 | # | |
| 771 | # This loop simply grabs the 3rd element of each line until | |
| 772 | # the EOF is reached. Each line overwrites the value of the | |
| 773 | # previous one so we're left with what we wanted. This isn't | |
| 774 | # slow as only 3 lines are parsed. | |
| 775 | while read -r _ _ line _; do | |
| 776 | mem_used=${line%%M}
| |
| 777 | ||
| 778 | # Using '<<-EOF' is the only way to loop over a command's | |
| 779 | # output without the use of a pipe ('|').
| |
| 780 | # This ensures that any variables defined in the while loop | |
| 781 | # are still accessible in the script. | |
| 782 | done <<-EOF | |
| 783 | $(vmstat) | |
| 784 | EOF | |
| 785 | ;; | |
| 786 | ||
| 787 | # Used memory is calculated using the following "formula": | |
| 788 | # mem_full - ((inactive + free + cache) * page_size / 1024) | |
| 789 | (FreeBSD*|DragonFly*) | |
| 790 | mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024)) | |
| 791 | ||
| 792 | # Use 'set --' to store the output of the command in the | |
| 793 | # argument list. POSIX sh has no arrays but this is close enough. | |
| 794 | # | |
| 795 | # Disable the shellcheck warning for word-splitting | |
| 796 | # as it's safe and intended ('set -f' disables globbing).
| |
| 797 | # shellcheck disable=2046 | |
| 798 | {
| |
| 799 | set -f | |
| 800 | set +f -- $(sysctl -n hw.pagesize \ | |
| 801 | vm.stats.vm.v_inactive_count \ | |
| 802 | vm.stats.vm.v_free_count \ | |
| 803 | vm.stats.vm.v_cache_count) | |
| 804 | } | |
| 805 | ||
| 806 | # Calculate the amount of used memory. | |
| 807 | # $1: hw.pagesize | |
| 808 | # $2: vm.stats.vm.v_inactive_count | |
| 809 | # $3: vm.stats.vm.v_free_count | |
| 810 | # $4: vm.stats.vm.v_cache_count | |
| 811 | mem_used=$((mem_full - (($2 + $3 + $4) * $1 / 1024 / 1024))) | |
| 812 | ;; | |
| 813 | ||
| 814 | (NetBSD*) | |
| 815 | mem_full=$(($(sysctl -n hw.physmem64) / 1024 / 1024)) | |
| 816 | ||
| 817 | # NetBSD implements a lot of the Linux '/proc' filesystem, | |
| 818 | # this uses the same parser as the Linux memory detection. | |
| 819 | while IFS=':k ' read -r key val _; do | |
| 820 | case $key in | |
| 821 | (MemFree) | |
| 822 | mem_free=$((val / 1024)) | |
| 823 | break | |
| 824 | ;; | |
| 825 | esac | |
| 826 | done < /proc/meminfo | |
| 827 | ||
| 828 | mem_used=$((mem_full - mem_free)) | |
| 829 | ;; | |
| 830 | ||
| 831 | (Haiku) | |
| 832 | # Read the first line of 'sysinfo -mem' splitting on | |
| 833 | # '(', ' ', and ')'. The needed information is then
| |
| 834 | # stored in the 5th and 7th elements. Using '_' "consumes" | |
| 835 | # an element allowing us to proceed to the next one. | |
| 836 | # | |
| 837 | # The parsed format is as follows: | |
| 838 | # 3501142016 bytes free (used/max 792645632 / 4293787648) | |
| 839 | IFS='( )' read -r _ _ _ _ mem_used _ mem_full <<-EOF | |
| 840 | $(sysinfo -mem) | |
| 841 | EOF | |
| 842 | ||
| 843 | mem_used=$((mem_used / 1024 / 1024)) | |
| 844 | mem_full=$((mem_full / 1024 / 1024)) | |
| 845 | ;; | |
| 846 | ||
| 847 | (Minix) | |
| 848 | # Minix includes the '/proc' filesystem though the format | |
| 849 | # differs from Linux. The '/proc/meminfo' file is only a | |
| 850 | # single line with space separated elements and elements | |
| 851 | # 2 and 3 contain the total and free memory numbers. | |
| 852 | read -r _ mem_full mem_free _ < /proc/meminfo | |
| 853 | ||
| 854 | mem_used=$(((mem_full - mem_free) / 1024)) | |
| 855 | mem_full=$(( mem_full / 1024)) | |
| 856 | ;; | |
| 857 | ||
| 858 | (SunOS) | |
| 859 | hw_pagesize=$(pagesize) | |
| 860 | ||
| 861 | # 'kstat' outputs memory in the following format: | |
| 862 | # unix:0:system_pages:pagestotal 1046397 | |
| 863 | # unix:0:system_pages:pagesfree 885018 | |
| 864 | # | |
| 865 | # This simply uses the first "element" (white-space | |
| 866 | # separated) as the key and the second element as the | |
| 867 | # value. | |
| 868 | # | |
| 869 | # A variable is then assigned based on the key. | |
| 870 | while read -r key val; do | |
| 871 | case $key in | |
| 872 | (*total) | |
| 873 | pages_full=$val | |
| 874 | ;; | |
| 875 | ||
| 876 | (*free) | |
| 877 | pages_free=$val | |
| 878 | ;; | |
| 879 | esac | |
| 880 | done <<-EOF | |
| 881 | $(kstat -p unix:0:system_pages:pagestotal \ | |
| 882 | unix:0:system_pages:pagesfree) | |
| 883 | EOF | |
| 884 | ||
| 885 | mem_full=$((pages_full * hw_pagesize / 1024 / 1024)) | |
| 886 | mem_free=$((pages_free * hw_pagesize / 1024 / 1024)) | |
| 887 | mem_used=$((mem_full - mem_free)) | |
| 888 | ;; | |
| 889 | ||
| 890 | (IRIX) | |
| 891 | # Read the memory information from the 'top' command. Parse | |
| 892 | # and split each line until we reach the line starting with | |
| 893 | # "Memory". | |
| 894 | # | |
| 895 | # Example output: Memory: 160M max, 147M avail, ..... | |
| 896 | while IFS=' :' read -r label mem_full _ mem_free _; do | |
| 897 | case $label in | |
| 898 | (Memory) | |
| 899 | mem_full=${mem_full%M}
| |
| 900 | mem_free=${mem_free%M}
| |
| 901 | break | |
| 902 | ;; | |
| 903 | esac | |
| 904 | done <<-EOF | |
| 905 | $(top -n) | |
| 906 | EOF | |
| 907 | ||
| 908 | mem_used=$((mem_full - mem_free)) | |
| 909 | ;; | |
| 910 | ||
| 911 | (SerenityOS) | |
| 912 | IFS='{}' read -r _ memstat _ < /proc/memstat
| |
| 913 | ||
| 914 | set -f -- "$IFS" | |
| 915 | IFS=, | |
| 916 | ||
| 917 | for pair in $memstat; do | |
| 918 | case $pair in | |
| 919 | (*user_physical_allocated*) | |
| 920 | mem_used=${pair##*:}
| |
| 921 | ;; | |
| 922 | ||
| 923 | (*user_physical_available*) | |
| 924 | mem_free=${pair##*:}
| |
| 925 | ;; | |
| 926 | esac | |
| 927 | done | |
| 928 | ||
| 929 | IFS=$1 | |
| 930 | set +f -- | |
| 931 | ||
| 932 | mem_used=$((mem_used * 4096 / 1024 / 1024)) | |
| 933 | mem_free=$((mem_free * 4096 / 1024 / 1024)) | |
| 934 | ||
| 935 | mem_full=$((mem_used + mem_free)) | |
| 936 | ;; | |
| 937 | esac | |
| 938 | ||
| 939 | log memory "${mem_used:-?}M / ${mem_full:-?}M" >&6
| |
| 940 | } | |
| 941 | ||
| 942 | get_wm() {
| |
| 943 | case $os in | |
| 944 | (Darwin*) | |
| 945 | # Don't display window manager on macOS. | |
| 946 | ;; | |
| 947 | ||
| 948 | (*) | |
| 949 | # xprop can be used to grab the window manager's properties | |
| 950 | # which contains the window manager's name under '_NET_WM_NAME'. | |
| 951 | # | |
| 952 | # The upside to using 'xprop' is that you don't need to hardcode | |
| 953 | # a list of known window manager names. The downside is that | |
| 954 | # not all window managers conform to setting the '_NET_WM_NAME' | |
| 955 | # atom.. | |
| 956 | # | |
| 957 | # List of window managers which fail to set the name atom: | |
| 958 | # catwm, fvwm, dwm, 2bwm, monster, wmaker and sowm [mine! ;)]. | |
| 959 | # | |
| 960 | # The final downside to this approach is that it does _not_ | |
| 961 | # support Wayland environments. The only solution which supports | |
| 962 | # Wayland is the 'ps' parsing mentioned below. | |
| 963 | # | |
| 964 | # A more naive implementation is to parse the last line of | |
| 965 | # '~/.xinitrc' to extract the second white-space separated | |
| 966 | # element. | |
| 967 | # | |
| 968 | # The issue with an approach like this is that this line data | |
| 969 | # does not always equate to the name of the window manager and | |
| 970 | # could in theory be _anything_. | |
| 971 | # | |
| 972 | # This also fails when the user launches xorg through a display | |
| 973 | # manager or other means. | |
| 974 | # | |
| 975 | # | |
| 976 | # Another naive solution is to parse 'ps' with a hardcoded list | |
| 977 | # of window managers to detect the current window manager (based | |
| 978 | # on what is running). | |
| 979 | # | |
| 980 | # The issue with this approach is the need to hardcode and | |
| 981 | # maintain a list of known window managers. | |
| 982 | # | |
| 983 | # Another issue is that process names do not always equate to | |
| 984 | # the name of the window manager. False-positives can happen too. | |
| 985 | # | |
| 986 | # This is the only solution which supports Wayland based | |
| 987 | # environments sadly. It'd be nice if some kind of standard were | |
| 988 | # established to identify Wayland environments. | |
| 989 | # | |
| 990 | # pfetch's goal is to remain _simple_, if you'd like a "full" | |
| 991 | # implementation of window manager detection use 'neofetch'. | |
| 992 | # | |
| 993 | # Neofetch use a combination of 'xprop' and 'ps' parsing to | |
| 994 | # support all window managers (including non-conforming and | |
| 995 | # Wayland) though it's a lot more complicated! | |
| 996 | ||
| 997 | # Don't display window manager if X isn't running. | |
| 998 | [ "$DISPLAY" ] || return | |
| 999 | ||
| 1000 | # This is a two pass call to xprop. One call to get the window | |
| 1001 | # manager's ID and another to print its properties. | |
| 1002 | has xprop && {
| |
| 1003 | # The output of the ID command is as follows: | |
| 1004 | # _NET_SUPPORTING_WM_CHECK: window id # 0x400000 | |
| 1005 | # | |
| 1006 | # To extract the ID, everything before the last space | |
| 1007 | # is removed. | |
| 1008 | id=$(xprop -root -notype _NET_SUPPORTING_WM_CHECK) | |
| 1009 | id=${id##* }
| |
| 1010 | ||
| 1011 | # The output of the property command is as follows: | |
| 1012 | # _NAME 8t | |
| 1013 | # _NET_WM_PID = 252 | |
| 1014 | # _NET_WM_NAME = "bspwm" | |
| 1015 | # _NET_SUPPORTING_WM_CHECK: window id # 0x400000 | |
| 1016 | # WM_CLASS = "wm", "Bspwm" | |
| 1017 | # | |
| 1018 | # To extract the name, everything before '_NET_WM_NAME = \"' | |
| 1019 | # is removed and everything after the next '"' is removed. | |
| 1020 | wm=$(xprop -id "$id" -notype -len 25 -f _NET_WM_NAME 8t) | |
| 1021 | } | |
| 1022 | ||
| 1023 | # Handle cases of a window manager _not_ populating the | |
| 1024 | # '_NET_WM_NAME' atom. Display nothing in this case. | |
| 1025 | case $wm in | |
| 1026 | (*'_NET_WM_NAME = '*) | |
| 1027 | wm=${wm##*_NET_WM_NAME = \"}
| |
| 1028 | wm=${wm%%\"*}
| |
| 1029 | ;; | |
| 1030 | ||
| 1031 | (*) | |
| 1032 | # Fallback to checking the process list | |
| 1033 | # for the select few window managers which | |
| 1034 | # don't set '_NET_WM_NAME'. | |
| 1035 | while read -r ps_line; do | |
| 1036 | case $ps_line in | |
| 1037 | (*catwm*) wm=catwm ;; | |
| 1038 | (*fvwm*) wm=fvwm ;; | |
| 1039 | (*dwm*) wm=dwm ;; | |
| 1040 | (*2bwm*) wm=2bwm ;; | |
| 1041 | (*monsterwm*) wm=monsterwm ;; | |
| 1042 | (*wmaker*) wm='Window Maker' ;; | |
| 1043 | (*sowm*) wm=sowm ;; | |
| 1044 | (*penrose*) wm=penrose ;; | |
| 1045 | esac | |
| 1046 | done <<-EOF | |
| 1047 | $(ps x) | |
| 1048 | EOF | |
| 1049 | ;; | |
| 1050 | esac | |
| 1051 | ;; | |
| 1052 | esac | |
| 1053 | ||
| 1054 | log wm "$wm" >&6 | |
| 1055 | } | |
| 1056 | ||
| 1057 | ||
| 1058 | get_de() {
| |
| 1059 | # This only supports Xorg related desktop environments though | |
| 1060 | # this is fine as knowing the desktop environment on Windows, | |
| 1061 | # macOS etc is useless (they'll always report the same value). | |
| 1062 | # | |
| 1063 | # Display the value of '$XDG_CURRENT_DESKTOP', if it's empty, | |
| 1064 | # display the value of '$DESKTOP_SESSION'. | |
| 1065 | log de "${XDG_CURRENT_DESKTOP:-$DESKTOP_SESSION}" >&6
| |
| 1066 | } | |
| 1067 | ||
| 1068 | get_shell() {
| |
| 1069 | # Display the basename of the '$SHELL' environment variable. | |
| 1070 | log shell "${SHELL##*/}" >&6
| |
| 1071 | } | |
| 1072 | ||
| 1073 | get_editor() {
| |
| 1074 | # Display the value of '$VISUAL', if it's empty, display the | |
| 1075 | # value of '$EDITOR'. | |
| 1076 | editor=${VISUAL:-"$EDITOR"}
| |
| 1077 | ||
| 1078 | log editor "${editor##*/}" >&6
| |
| 1079 | } | |
| 1080 | ||
| 1081 | get_palette() {
| |
| 1082 | # Print the first 8 terminal colors. This uses the existing | |
| 1083 | # sequences to change text color with a sequence prepended | |
| 1084 | # to reverse the foreground and background colors. | |
| 1085 | # | |
| 1086 | # This allows us to save hardcoding a second set of sequences | |
| 1087 | # for background colors. | |
| 1088 | # | |
| 1089 | # False positive. | |
| 1090 | # shellcheck disable=2154 | |
| 1091 | {
| |
| 1092 | esc SGR 7 | |
| 1093 | palette="$e$c1 $c1 $c2 $c2 $c3 $c3 $c4 $c4 $c5 $c5 $c6 $c6 " | |
| 1094 | esc SGR 0 | |
| 1095 | palette="$palette$e" | |
| 1096 | } | |
| 1097 | ||
| 1098 | # Print the palette with a new-line before and afterwards but no seperator. | |
| 1099 | printf '\n' >&6 | |
| 1100 | log "$palette | |
| 1101 | " " " " " >&6 | |
| 1102 | } | |
| 1103 | ||
| 1104 | get_ascii() {
| |
| 1105 | # This is a simple function to read the contents of | |
| 1106 | # an ascii file from 'stdin'. It allows for the use | |
| 1107 | # of '<<-EOF' to prevent the break in indentation in | |
| 1108 | # this source code. | |
| 1109 | # | |
| 1110 | # This function also sets the text colors according | |
| 1111 | # to the ascii color. | |
| 1112 | read_ascii() {
| |
| 1113 | # 'PF_COL1': Set the info name color according to ascii color. | |
| 1114 | # 'PF_COL3': Set the title color to some other color. ¯\_(ツ)_/¯ | |
| 1115 | PF_COL1=${PF_COL1:-${1:-7}}
| |
| 1116 | PF_COL3=${PF_COL3:-$((${1:-7}%8+1))}
| |
| 1117 | ||
| 1118 | # POSIX sh has no 'var+=' so 'var=${var}append' is used. What's
| |
| 1119 | # interesting is that 'var+=' _is_ supported inside '$(())' | |
| 1120 | # (arithmetic) though there's no support for 'var++/var--'. | |
| 1121 | # | |
| 1122 | # There is also no $'\n' to add a "literal"(?) newline to the | |
| 1123 | # string. The simplest workaround being to break the line inside | |
| 1124 | # the string (though this has the caveat of breaking indentation). | |
| 1125 | while IFS= read -r line; do | |
| 1126 | ascii="$ascii$line | |
| 1127 | " | |
| 1128 | done | |
| 1129 | } | |
| 1130 | ||
| 1131 | # This checks for ascii art in the following order: | |
| 1132 | # '$1': Argument given to 'get_ascii()' directly. | |
| 1133 | # '$PF_ASCII': Environment variable set by user. | |
| 1134 | # '$distro': The detected distribution name. | |
| 1135 | # '$os': The name of the operating system/kernel. | |
| 1136 | # | |
| 1137 | # NOTE: Each ascii art below is indented using tabs, this | |
| 1138 | # allows indentation to continue naturally despite | |
| 1139 | # the use of '<<-EOF'. | |
| 1140 | # | |
| 1141 | # False positive. | |
| 1142 | # shellcheck disable=2154 | |
| 1143 | case ${1:-${PF_ASCII:-${distro:-$os}}} in
| |
| 1144 | ([Aa]lpine*) | |
| 1145 | read_ascii 4 <<-EOF | |
| 1146 | ${c4} /\\ /\\
| |
| 1147 | /${c7}/ ${c4}\\ \\
| |
| 1148 | /${c7}/ ${c4}\\ \\
| |
| 1149 | /${c7}// ${c4}\\ \\
| |
| 1150 | ${c7}// ${c4}\\ \\
| |
| 1151 | ${c4}\\
| |
| 1152 | EOF | |
| 1153 | ;; | |
| 1154 | ||
| 1155 | ([Aa]ndroid*) | |
| 1156 | read_ascii 2 <<-EOF | |
| 1157 | ${c2} ;, ,;
| |
| 1158 | ${c2} ';,.-----.,;'
| |
| 1159 | ${c2} ,' ',
| |
| 1160 | ${c2} / O O \\
| |
| 1161 | ${c2}| |
| |
| 1162 | ${c2}'-----------------'
| |
| 1163 | EOF | |
| 1164 | ;; | |
| 1165 | ||
| 1166 | ([Aa]rch*) | |
| 1167 | read_ascii 4 <<-EOF | |
| 1168 | ${c6} /\\
| |
| 1169 | ${c6} / \\
| |
| 1170 | ${c6} /\\ \\
| |
| 1171 | ${c4} / \\
| |
| 1172 | ${c4} / ,, \\
| |
| 1173 | ${c4} / | | -\\
| |
| 1174 | ${c4} /_-'' ''-_\\
| |
| 1175 | EOF | |
| 1176 | ;; | |
| 1177 | ||
| 1178 | ([Aa]rco*) | |
| 1179 | read_ascii 4 <<-EOF | |
| 1180 | ${c4} /\\
| |
| 1181 | ${c4} / \\
| |
| 1182 | ${c4} / /\\ \\
| |
| 1183 | ${c4} / / \\ \\
| |
| 1184 | ${c4} / / \\ \\
| |
| 1185 | ${c4} / / _____\\ \\
| |
| 1186 | ${c4}/_/ \`----.\\_\\
| |
| 1187 | EOF | |
| 1188 | ;; | |
| 1189 | ||
| 1190 | ([Aa]rtix*) | |
| 1191 | read_ascii 6 <<-EOF | |
| 1192 | ${c4} /\\
| |
| 1193 | ${c4} / \\
| |
| 1194 | ${c4} /\`'.,\\
| |
| 1195 | ${c4} / ',
| |
| 1196 | ${c4} / ,\`\\
| |
| 1197 | ${c4} / ,.'\`. \\
| |
| 1198 | ${c4}/.,'\` \`'.\\
| |
| 1199 | EOF | |
| 1200 | ;; | |
| 1201 | ||
| 1202 | ([Bb]edrock*) | |
| 1203 | read_ascii 4 <<-EOF | |
| 1204 | ${c7}__
| |
| 1205 | ${c7}\\ \\___
| |
| 1206 | ${c7} \\ _ \\
| |
| 1207 | ${c7} \\___/
| |
| 1208 | EOF | |
| 1209 | ;; | |
| 1210 | ||
| 1211 | ([Bb]uildroot*) | |
| 1212 | read_ascii 3 <<-EOF | |
| 1213 | ${c3} ___
| |
| 1214 | ${c3} / \` \\
| |
| 1215 | ${c3}| : :|
| |
| 1216 | ${c3}-. _:__.-
| |
| 1217 | ${c3} \` ---- \`
| |
| 1218 | EOF | |
| 1219 | ;; | |
| 1220 | ||
| 1221 | ([Cc]el[Oo][Ss]*) | |
| 1222 | read_ascii 5 0 <<-EOF | |
| 1223 | ${c5} .////\\\\\//\\.
| |
| 1224 | ${c5} //_ \\\\
| |
| 1225 | ${c5} /_ ${c7}##############
| |
| 1226 | ${c5} // *\\
| |
| 1227 | ${c7}############### ${c5}|#
| |
| 1228 | ${c5} \/ */
| |
| 1229 | ${c5} \* ${c7}##############
| |
| 1230 | ${c5} */, .//
| |
| 1231 | ${c5} '_///\\\\\//_'
| |
| 1232 | EOF | |
| 1233 | ;; | |
| 1234 | ||
| 1235 | ([Cc]ent[Oo][Ss]*) | |
| 1236 | read_ascii 5 <<-EOF | |
| 1237 | ${c2} ____${c3}^${c5}____
| |
| 1238 | ${c2} |\\ ${c3}|${c5} /|
| |
| 1239 | ${c2} | \\ ${c3}|${c5} / |
| |
| 1240 | ${c5}<---- ${c4}---->
| |
| 1241 | ${c4} | / ${c2}|${c3} \\ |
| |
| 1242 | ${c4} |/__${c2}|${c3}__\\|
| |
| 1243 | ${c2} v
| |
| 1244 | EOF | |
| 1245 | ;; | |
| 1246 | ||
| 1247 | ([Cc]rystal*[Ll]inux) | |
| 1248 | read_ascii 5 5 <<-EOF | |
| 1249 | ${c5} -//.
| |
| 1250 | ${c5} -//.
| |
| 1251 | ${c5} -//. .
| |
| 1252 | ${c5} -//. '//-
| |
| 1253 | ${c5} /+: :+/
| |
| 1254 | ${c5} .//' .//.
| |
| 1255 | ${c5} . .//.
| |
| 1256 | ${c5} .//.
| |
| 1257 | ${c5} .//.
| |
| 1258 | EOF | |
| 1259 | ;; | |
| 1260 | ||
| 1261 | ([Dd]ahlia*) | |
| 1262 | read_ascii 1 <<-EOF | |
| 1263 | ${c1} _
| |
| 1264 | ${c1} ___/ \\___
| |
| 1265 | ${c1} | _-_ |
| |
| 1266 | ${c1} | / \ |
| |
| 1267 | ${c1}/ | | \\
| |
| 1268 | ${c1}\\ | | /
| |
| 1269 | ${c1} | \ _ _ / |
| |
| 1270 | ${c1} |___ - ___|
| |
| 1271 | ${c1} \\_/
| |
| 1272 | EOF | |
| 1273 | ;; | |
| 1274 | ||
| 1275 | ([Dd]ebian*) | |
| 1276 | read_ascii 1 <<-EOF | |
| 1277 | ${c1} _____
| |
| 1278 | ${c1} / __ \\
| |
| 1279 | ${c1}| / |
| |
| 1280 | ${c1}| \\___-
| |
| 1281 | ${c1}-_
| |
| 1282 | ${c1} --_
| |
| 1283 | EOF | |
| 1284 | ;; | |
| 1285 | ||
| 1286 | ([Dd]evuan*) | |
| 1287 | read_ascii 6 <<-EOF | |
| 1288 | ${c4} ..:::.
| |
| 1289 | ${c4} ..-==-
| |
| 1290 | ${c4} .+#:
| |
| 1291 | ${c4} =@@
| |
| 1292 | ${c4} :+%@#:
| |
| 1293 | ${c4}.:=+#@@%*:
| |
| 1294 | ${c4}#@@@#=:
| |
| 1295 | EOF | |
| 1296 | ;; | |
| 1297 | ||
| 1298 | ([Dd]ragon[Ff]ly*) | |
| 1299 | read_ascii 1 <<-EOF | |
| 1300 | ,${c1}_${c7},
| |
| 1301 | ('-_${c1}|${c7}_-')
| |
| 1302 | >--${c1}|${c7}--<
| |
| 1303 | (_-'${c1}|${c7}'-_)
| |
| 1304 | ${c1}|
| |
| 1305 | ${c1}|
| |
| 1306 | ${c1}|
| |
| 1307 | EOF | |
| 1308 | ;; | |
| 1309 | ||
| 1310 | ([Ee]lementary*) | |
| 1311 | read_ascii <<-EOF | |
| 1312 | ${c7} _______
| |
| 1313 | ${c7} / ____ \\
| |
| 1314 | ${c7}/ | / /\\
| |
| 1315 | ${c7}|__\\ / / |
| |
| 1316 | ${c7}\\ /__/ /
| |
| 1317 | ${c7}\\_______/
| |
| 1318 | EOF | |
| 1319 | ;; | |
| 1320 | ||
| 1321 | ([Ee]ndeavour*) | |
| 1322 | read_ascii 4 <<-EOF | |
| 1323 | ${c1}/${c4}\\
| |
| 1324 | ${c1}/${c4}/ \\${c6}\\
| |
| 1325 | ${c1}/${c4}/ \\ ${c6}\\
| |
| 1326 | ${c1}/ ${c4}/ _) ${c6})
| |
| 1327 | ${c1}/_${c4}/___-- ${c6}__-
| |
| 1328 | ${c6}/____--
| |
| 1329 | EOF | |
| 1330 | ;; | |
| 1331 | ||
| 1332 | ([Ff]edora*) | |
| 1333 | read_ascii 4 <<-EOF | |
| 1334 | ${c4},'''''.
| |
| 1335 | ${c4}| ,. |
| |
| 1336 | ${c4}| | '_'
| |
| 1337 | ${c4} ,....| |..
| |
| 1338 | ${c4}.' ,_;| ..'
| |
| 1339 | ${c4}| | | |
| |
| 1340 | ${c4}| ',_,' |
| |
| 1341 | ${c4} '. ,'
| |
| 1342 | ${c4}'''''
| |
| 1343 | EOF | |
| 1344 | ;; | |
| 1345 | ||
| 1346 | ([Ff]ree[Bb][Ss][Dd]*) | |
| 1347 | read_ascii 1 <<-EOF | |
| 1348 | ${c1}/\\,-'''''-,/\\
| |
| 1349 | ${c1}\\_) (_/
| |
| 1350 | ${c1}| |
| |
| 1351 | ${c1}| |
| |
| 1352 | ${c1}; ;
| |
| 1353 | ${c1}'-_____-'
| |
| 1354 | EOF | |
| 1355 | ;; | |
| 1356 | ||
| 1357 | ([Gg]aruda*) | |
| 1358 | read_ascii 4 <<-EOF | |
| 1359 | ${c3} _______
| |
| 1360 | ${c3} __/ \\_
| |
| 1361 | ${c3} _/ / \\_
| |
| 1362 | ${c7} _/ /_________\\
| |
| 1363 | ${c7}_/ |
| |
| 1364 | ${c2}\\ ____________
| |
| 1365 | ${c2} \\_ __/
| |
| 1366 | ${c2} \\__________/
| |
| 1367 | EOF | |
| 1368 | ;; | |
| 1369 | ||
| 1370 | ([Gg]entoo*) | |
| 1371 | read_ascii 5 <<-EOF | |
| 1372 | ${c5} _-----_
| |
| 1373 | ${c5}( \\
| |
| 1374 | ${c5}\\ 0 \\
| |
| 1375 | ${c7} \\ )
| |
| 1376 | ${c7} / _/
| |
| 1377 | ${c7}( _-
| |
| 1378 | ${c7}\\____-
| |
| 1379 | EOF | |
| 1380 | ;; | |
| 1381 | ||
| 1382 | ([Gg][Nn][Uu]*) | |
| 1383 | read_ascii 3 <<-EOF | |
| 1384 | ${c2} _-\`\`-, ,-\`\`-_
| |
| 1385 | ${c2} .' _-_| |_-_ '.
| |
| 1386 | ${c2}./ /_._ _._\\ \\.
| |
| 1387 | ${c2}: _/_._\`:'_._\\_ :
| |
| 1388 | ${c2}\\:._/ ,\` \\ \\ \\_.:/
| |
| 1389 | ${c2} ,-';'.@) \\ @) \\
| |
| 1390 | ${c2} ,'/' ..- .\\,-.|
| |
| 1391 | ${c2} /'/' \\(( \\\` ./ )
| |
| 1392 | ${c2} '/'' \\_,----'
| |
| 1393 | ${c2} '/'' ,;/''
| |
| 1394 | ${c2} \`\`;'
| |
| 1395 | EOF | |
| 1396 | ;; | |
| 1397 | ||
| 1398 | ([Gg]uix[Ss][Dd]*|[Gg]uix*) | |
| 1399 | read_ascii 3 <<-EOF | |
| 1400 | ${c3}|.__ __.|
| |
| 1401 | ${c3}|__ \\ / __|
| |
| 1402 | ${c3}\\ \\ / /
| |
| 1403 | ${c3}\\ \\ / /
| |
| 1404 | ${c3}\\ \\ / /
| |
| 1405 | ${c3}\\ \\/ /
| |
| 1406 | ${c3}\\__/
| |
| 1407 | EOF | |
| 1408 | ;; | |
| 1409 | ||
| 1410 | ([Hh]aiku*) | |
| 1411 | read_ascii 3 <<-EOF | |
| 1412 | ${c3} ,^,
| |
| 1413 | ${c3} / \\
| |
| 1414 | ${c3}*--_ ; ; _--*
| |
| 1415 | ${c3}\\ '" "' /
| |
| 1416 | ${c3}'. .'
| |
| 1417 | ${c3}.-'" "'-.
| |
| 1418 | ${c3}'-.__. .__.-'
| |
| 1419 | ${c3}|_|
| |
| 1420 | EOF | |
| 1421 | ;; | |
| 1422 | ||
| 1423 | ([Hh]ydroOS*) | |
| 1424 | read_ascii 4 <<-EOF | |
| 1425 | ${c1}╔╗╔╗──╔╗───╔═╦══╗
| |
| 1426 | ${c1}║╚╝╠╦╦╝╠╦╦═╣║║══╣
| |
| 1427 | ${c1}║╔╗║║║╬║╔╣╬║║╠══║
| |
| 1428 | ${c1}╚╝╚╬╗╠═╩╝╚═╩═╩══╝
| |
| 1429 | ${c1}───╚═╝
| |
| 1430 | EOF | |
| 1431 | ;; | |
| 1432 | ||
| 1433 | ([Hh]yperbola*) | |
| 1434 | read_ascii <<-EOF | |
| 1435 | ${c7} |\`__.\`/
| |
| 1436 | ${c7} \____/
| |
| 1437 | ${c7} .--.
| |
| 1438 | ${c7} / \\
| |
| 1439 | ${c7} / ___ \\
| |
| 1440 | ${c7}/ .\` \`.\\
| |
| 1441 | ${c7}/.\` \`.\\
| |
| 1442 | EOF | |
| 1443 | ;; | |
| 1444 | ||
| 1445 | ([Ii]glunix*) | |
| 1446 | read_ascii <<-EOF | |
| 1447 | ${c0} |
| |
| 1448 | ${c0} | |
| |
| 1449 | ${c0} |
| |
| 1450 | ${c0} | ________
| |
| 1451 | ${c0} | /\\ | \\
| |
| 1452 | ${c0} / \\ | \\ |
| |
| 1453 | ${c0} / \\ \\ |
| |
| 1454 | ${c0} / \\________\\
| |
| 1455 | ${c0} \\ / /
| |
| 1456 | ${c0} \\ / /
| |
| 1457 | ${c0} \\ / /
| |
| 1458 | ${c0} \\/________/
| |
| 1459 | EOF | |
| 1460 | ;; | |
| 1461 | ||
| 1462 | ([Ii]nstant[Oo][Ss]*) | |
| 1463 | read_ascii <<-EOF | |
| 1464 | ${c0} ,-''-,
| |
| 1465 | ${c0}: .''. :
| |
| 1466 | ${c0}: ',,' :
| |
| 1467 | ${c0} '-____:__
| |
| 1468 | ${c0} : \`.
| |
| 1469 | ${c0} \`._.'
| |
| 1470 | EOF | |
| 1471 | ;; | |
| 1472 | ||
| 1473 | ([Ii][Rr][Ii][Xx]*) | |
| 1474 | read_ascii 1 <<-EOF | |
| 1475 | ${c1} __
| |
| 1476 | ${c1} \\ \\ __
| |
| 1477 | ${c1} \\ \\ / /
| |
| 1478 | ${c1} \\ v /
| |
| 1479 | ${c1} / . \\
| |
| 1480 | ${c1} /_/ \\ \\
| |
| 1481 | ${c1} \\_\\
| |
| 1482 | EOF | |
| 1483 | ;; | |
| 1484 | ||
| 1485 | ([Kk][Dd][Ee]*[Nn]eon*) | |
| 1486 | read_ascii 6 <<-EOF | |
| 1487 | ${c7} .${c6}__${c7}.${c6}__${c7}.
| |
| 1488 | ${c6} / _${c7}.${c6}_ \\
| |
| 1489 | ${c6} / / \\ \\
| |
| 1490 | ${c7} . ${c6}| ${c7}O${c6} | ${c7}.
| |
| 1491 | ${c6} \\ \\_${c7}.${c6}_/ /
| |
| 1492 | ${c6} \\${c7}.${c6}__${c7}.${c6}__${c7}.${c6}/
| |
| 1493 | EOF | |
| 1494 | ;; | |
| 1495 | ||
| 1496 | ([Ll]inux*[Ll]ite*|[Ll]ite*) | |
| 1497 | read_ascii 3 <<-EOF | |
| 1498 | ${c3} /\\
| |
| 1499 | ${c3} / \\
| |
| 1500 | ${c3} / ${c7}/ ${c3}/
| |
| 1501 | ${c3}> ${c7}/ ${c3}/
| |
| 1502 | ${c3}\\ ${c7}\\ ${c3}\\
| |
| 1503 | ${c3}\\_${c7}\\${c3}_\\
| |
| 1504 | ${c7} \\
| |
| 1505 | EOF | |
| 1506 | ;; | |
| 1507 | ||
| 1508 | ([Ll]inux*[Mm]int*|[Mm]int) | |
| 1509 | read_ascii 2 <<-EOF | |
| 1510 | ${c2} ___________
| |
| 1511 | ${c2}|_ \\
| |
| 1512 | ${c2}| ${c7}| _____ ${c2}|
| |
| 1513 | ${c2}| ${c7}| | | | ${c2}|
| |
| 1514 | ${c2}| ${c7}| | | | ${c2}|
| |
| 1515 | ${c2}| ${c7}\\__${c7}___/ ${c2}|
| |
| 1516 | ${c2}\\_________/
| |
| 1517 | EOF | |
| 1518 | ;; | |
| 1519 | ||
| 1520 | ||
| 1521 | ([Ll]inux*) | |
| 1522 | read_ascii 4 <<-EOF | |
| 1523 | ${c4} ___
| |
| 1524 | ${c4}(${c7}.. ${c4}|
| |
| 1525 | ${c4}(${c5}<> ${c4}|
| |
| 1526 | ${c4}/ ${c7}__ ${c4}\\
| |
| 1527 | ${c4}( ${c7}/ \\ ${c4}/|
| |
| 1528 | ${c5}_${c4}/\\ ${c7}__)${c4}/${c5}_${c4})
| |
| 1529 | ${c5}\/${c4}-____${c5}\/
| |
| 1530 | EOF | |
| 1531 | ;; | |
| 1532 | ||
| 1533 | ([Mm]ac[Oo][Ss]*|[Dd]arwin*) | |
| 1534 | read_ascii 1 <<-EOF | |
| 1535 | ${c2} .:'
| |
| 1536 | ${c2} _ :'_
| |
| 1537 | ${c3} .'\`_\`-'_\`\`.
| |
| 1538 | ${c1}:________.-'
| |
| 1539 | ${c1}:_______:
| |
| 1540 | ${c4} :_______\`-;
| |
| 1541 | ${c5} \`._.-._.'
| |
| 1542 | EOF | |
| 1543 | ;; | |
| 1544 | ||
| 1545 | ([Mm]ageia*) | |
| 1546 | read_ascii 2 <<-EOF | |
| 1547 | ${c6} *
| |
| 1548 | ${c6} *
| |
| 1549 | ${c6} **
| |
| 1550 | ${c7} /\\__/\\
| |
| 1551 | ${c7}/ \\
| |
| 1552 | ${c7}\\ /
| |
| 1553 | ${c7} \\____/
| |
| 1554 | EOF | |
| 1555 | ;; | |
| 1556 | ||
| 1557 | ([Mm]anjaro*) | |
| 1558 | read_ascii 2 <<-EOF | |
| 1559 | ${c2}||||||||| ||||
| |
| 1560 | ${c2}||||||||| ||||
| |
| 1561 | ${c2}|||| ||||
| |
| 1562 | ${c2}|||| |||| ||||
| |
| 1563 | ${c2}|||| |||| ||||
| |
| 1564 | ${c2}|||| |||| ||||
| |
| 1565 | ${c2}|||| |||| ||||
| |
| 1566 | EOF | |
| 1567 | ;; | |
| 1568 | ||
| 1569 | ([Mm]inix*) | |
| 1570 | read_ascii 4 <<-EOF | |
| 1571 | ${c4} ,, ,,
| |
| 1572 | ${c4};${c7},${c4} ', ,' ${c7},${c4};
| |
| 1573 | ${c4}; ${c7}',${c4} ',,' ${c7},'${c4} ;
| |
| 1574 | ${c4}; ${c7}',${c4} ${c7},'${c4} ;
| |
| 1575 | ${c4}; ${c7};, '' ,;${c4} ;
| |
| 1576 | ${c4}; ${c7};${c4};${c7}',,'${c4};${c7};${c4} ;
| |
| 1577 | ${c4}', ${c7};${c4};; ;;${c7};${c4} ,'
| |
| 1578 | ${c4} '${c7};${c4}' '${c7};${c4}'
| |
| 1579 | EOF | |
| 1580 | ;; | |
| 1581 | ||
| 1582 | ([Mm][Xx]*) | |
| 1583 | read_ascii <<-EOF | |
| 1584 | ${c7} \\\\ /
| |
| 1585 | ${c7} \\\\/
| |
| 1586 | ${c7} \\\\
| |
| 1587 | ${c7} /\\/ \\\\
| |
| 1588 | ${c7} / \\ /\\
| |
| 1589 | ${c7} / \\/ \\
| |
| 1590 | ${c7}/__________\\
| |
| 1591 | EOF | |
| 1592 | ;; | |
| 1593 | ||
| 1594 | ([Nn]et[Bb][Ss][Dd]*) | |
| 1595 | read_ascii 3 <<-EOF | |
| 1596 | ${c7}\\\\${c3}\`-______,----__
| |
| 1597 | ${c7} \\\\ ${c3}__,---\`_
| |
| 1598 | ${c7} \\\\ ${c3}\`.____
| |
| 1599 | ${c7} \\\\${c3}-______,----\`-
| |
| 1600 | ${c7} \\\\
| |
| 1601 | ${c7} \\\\
| |
| 1602 | ${c7} \\\\
| |
| 1603 | EOF | |
| 1604 | ;; | |
| 1605 | ||
| 1606 | ([Nn]ix[Oo][Ss]*) | |
| 1607 | read_ascii 4 <<-EOF | |
| 1608 | ${c4} \\\\ \\\\ //
| |
| 1609 | ${c4} ==\\\\__\\\\/ //
| |
| 1610 | ${c4} // \\\\//
| |
| 1611 | ${c4}==// //==
| |
| 1612 | ${c4} //\\\\___//
| |
| 1613 | ${c4}// /\\\\ \\\\==
| |
| 1614 | ${c4} // \\\\ \\\\
| |
| 1615 | EOF | |
| 1616 | ;; | |
| 1617 | ||
| 1618 | ([Oo]pen[Bb][Ss][Dd]*) | |
| 1619 | read_ascii 3 <<-EOF | |
| 1620 | ${c3} _____
| |
| 1621 | ${c3} \\- -/
| |
| 1622 | ${c3} \\_/ \\
| |
| 1623 | ${c3} | ${c7}O O${c3} |
| |
| 1624 | ${c3} |_ < ) 3 )
| |
| 1625 | ${c3} / \\ /
| |
| 1626 | ${c3} /-_____-\\
| |
| 1627 | EOF | |
| 1628 | ;; | |
| 1629 | ||
| 1630 | ([Oo]pen[Ss][Uu][Ss][Ee]*[Tt]umbleweed*) | |
| 1631 | read_ascii 2 <<-EOF | |
| 1632 | ${c2} _____ ______
| |
| 1633 | ${c2} / ____\\ / ____ \\
| |
| 1634 | ${c2}/ / \`/ / \\ \\
| |
| 1635 | ${c2}\\ \\____/ /,____/ /
| |
| 1636 | ${c2} \\______/ \\_____/
| |
| 1637 | EOF | |
| 1638 | ;; | |
| 1639 | ||
| 1640 | ([Oo]pen[Ss][Uu][Ss][Ee]*|[Oo]pen*SUSE*|SUSE*|suse*) | |
| 1641 | read_ascii 2 <<-EOF | |
| 1642 | ${c2} _______
| |
| 1643 | ${c2}__| __ \\
| |
| 1644 | ${c2} / .\\ \\
| |
| 1645 | ${c2} \\__/ |
| |
| 1646 | ${c2} _______|
| |
| 1647 | ${c2} \\_______
| |
| 1648 | ${c2}__________/
| |
| 1649 | EOF | |
| 1650 | ;; | |
| 1651 | ||
| 1652 | ([Oo]pen[Ww]rt*) | |
| 1653 | read_ascii 1 <<-EOF | |
| 1654 | ${c1} _______
| |
| 1655 | ${c1}| |.-----.-----.-----.
| |
| 1656 | ${c1}| - || _ | -__| |
| |
| 1657 | ${c1}|_______|| __|_____|__|__|
| |
| 1658 | ${c1} ________|__| __
| |
| 1659 | ${c1}| | | |.----.| |_
| |
| 1660 | ${c1}| | | || _|| _|
| |
| 1661 | ${c1}|________||__| |____|
| |
| 1662 | EOF | |
| 1663 | ;; | |
| 1664 | ||
| 1665 | ([Pp]arabola*) | |
| 1666 | read_ascii 5 <<-EOF | |
| 1667 | ${c5} __ __ __ _
| |
| 1668 | ${c5}.\`_//_//_/ / \`.
| |
| 1669 | ${c5} / .\`
| |
| 1670 | ${c5} / .\`
| |
| 1671 | ${c5} /.\`
| |
| 1672 | ${c5} /\`
| |
| 1673 | EOF | |
| 1674 | ;; | |
| 1675 | ||
| 1676 | ([Pp]op!_[Oo][Ss]*) | |
| 1677 | read_ascii 6 <<-EOF | |
| 1678 | ${c6}______
| |
| 1679 | ${c6}\\ _ \\ __
| |
| 1680 | ${c6}\\ \\ \\ \\ / /
| |
| 1681 | ${c6}\\ \\_\\ \\ / /
| |
| 1682 | ${c6}\\ ___\\ /_/
| |
| 1683 | ${c6} \\ \\ _
| |
| 1684 | ${c6} __\\_\\__(_)_
| |
| 1685 | ${c6}(___________)
| |
| 1686 | EOF | |
| 1687 | ;; | |
| 1688 | ||
| 1689 | ([Pp]ure[Oo][Ss]*) | |
| 1690 | read_ascii <<-EOF | |
| 1691 | ${c7} _____________
| |
| 1692 | ${c7}| _________ |
| |
| 1693 | ${c7}| | | |
| |
| 1694 | ${c7}| | | |
| |
| 1695 | ${c7}| |_________| |
| |
| 1696 | ${c7}|_____________|
| |
| 1697 | EOF | |
| 1698 | ;; | |
| 1699 | ||
| 1700 | ([Rr]aspbian*) | |
| 1701 | read_ascii 1 <<-EOF | |
| 1702 | ${c2} __ __
| |
| 1703 | ${c2} (_\\)(/_)
| |
| 1704 | ${c1} (_(__)_)
| |
| 1705 | ${c1}(_(_)(_)_)
| |
| 1706 | ${c1} (_(__)_)
| |
| 1707 | ${c1} (__)
| |
| 1708 | EOF | |
| 1709 | ;; | |
| 1710 | ||
| 1711 | ([Ss]erenity[Oo][Ss]*) | |
| 1712 | read_ascii 4 <<-EOF | |
| 1713 | ${c7} _____
| |
| 1714 | ${c1} ,-${c7} -,
| |
| 1715 | ${c1} ;${c7} ( ;
| |
| 1716 | ${c1}| ${c7}. \_${c1}.,${c7} |
| |
| 1717 | ${c1}| ${c7}o _${c1} ',${c7} |
| |
| 1718 | ${c1} ; ${c7}(_)${c1} )${c7} ;
| |
| 1719 | ${c1} '-_____-${c7}'
| |
| 1720 | EOF | |
| 1721 | ;; | |
| 1722 | ||
| 1723 | ([Ss]lackware*) | |
| 1724 | read_ascii 4 <<-EOF | |
| 1725 | ${c4} ________
| |
| 1726 | ${c4} / ______|
| |
| 1727 | ${c4} | |______
| |
| 1728 | ${c4} \\______ \\
| |
| 1729 | ${c4} ______| |
| |
| 1730 | ${c4}| |________/
| |
| 1731 | ${c4}|____________
| |
| 1732 | EOF | |
| 1733 | ;; | |
| 1734 | ||
| 1735 | ([Ss]olus*) | |
| 1736 | read_ascii 4 <<-EOF | |
| 1737 | ${c6}
| |
| 1738 | ${c6} /|
| |
| 1739 | ${c6} / |\\
| |
| 1740 | ${c6} / | \\ _
| |
| 1741 | ${c6} /___|__\\_\\
| |
| 1742 | ${c6} \\ /
| |
| 1743 | ${c6} \`-------´
| |
| 1744 | EOF | |
| 1745 | ;; | |
| 1746 | ||
| 1747 | ([Ss]un[Oo][Ss]|[Ss]olaris*) | |
| 1748 | read_ascii 3 <<-EOF | |
| 1749 | ${c3} . .; .
| |
| 1750 | ${c3} . :; :: ;: .
| |
| 1751 | ${c3} .;. .. .. .;.
| |
| 1752 | ${c3}.. .. .. ..
| |
| 1753 | ${c3} .;, ,;.
| |
| 1754 | EOF | |
| 1755 | ;; | |
| 1756 | ||
| 1757 | ([Uu]buntu*) | |
| 1758 | read_ascii 3 <<-EOF | |
| 1759 | ${c3} _
| |
| 1760 | ${c3} ---(_)
| |
| 1761 | ${c3} _/ --- \\
| |
| 1762 | ${c3}(_) | |
| |
| 1763 | ${c3} \\ --- _/
| |
| 1764 | ${c3} ---(_)
| |
| 1765 | EOF | |
| 1766 | ;; | |
| 1767 | ||
| 1768 | ([Vv]oid*) | |
| 1769 | read_ascii 2 <<-EOF | |
| 1770 | ${c2} _______
| |
| 1771 | ${c2} _ \\______ -
| |
| 1772 | ${c2}| \\ ___ \\ |
| |
| 1773 | ${c2}| | / \ | |
| |
| 1774 | ${c2}| | \___/ | |
| |
| 1775 | ${c2}| \\______ \\_|
| |
| 1776 | ${c2} -_______\\
| |
| 1777 | EOF | |
| 1778 | ;; | |
| 1779 | ||
| 1780 | ([Xx]eonix*) | |
| 1781 | read_ascii 2 <<-EOF | |
| 1782 | ${c2} ___ ___
| |
| 1783 | ${c2}___ \ \/ / ___
| |
| 1784 | ${c2}\ \ \ / / /
| |
| 1785 | ${c2} \ \/ \/ /
| |
| 1786 | ${c2} \ /\ /
| |
| 1787 | ${c2} \__/ \__/
| |
| 1788 | EOF | |
| 1789 | ;; | |
| 1790 | ||
| 1791 | (*) | |
| 1792 | # On no match of a distribution ascii art, this function calls | |
| 1793 | # itself again, this time to look for a more generic OS related | |
| 1794 | # ascii art (KISS Linux -> Linux). | |
| 1795 | [ "$1" ] || {
| |
| 1796 | get_ascii "$os" | |
| 1797 | return | |
| 1798 | } | |
| 1799 | ||
| 1800 | printf 'error: %s is not currently supported.\n' "$os" >&6 | |
| 1801 | printf 'error: Open an issue for support to be added.\n' >&6 | |
| 1802 | exit 1 | |
| 1803 | ;; | |
| 1804 | esac | |
| 1805 | ||
| 1806 | # Store the "width" (longest line) and "height" (number of lines) | |
| 1807 | # of the ascii art for positioning. This script prints to the screen | |
| 1808 | # *almost* like a TUI does. It uses escape sequences to allow dynamic | |
| 1809 | # printing of the information through user configuration. | |
| 1810 | # | |
| 1811 | # Iterate over each line of the ascii art to retrieve the above | |
| 1812 | # information. The 'sed' is used to strip '\033[3Xm' color codes from | |
| 1813 | # the ascii art so they don't affect the width variable. | |
| 1814 | while read -r line; do | |
| 1815 | ascii_height=$((${ascii_height:-0} + 1))
| |
| 1816 | ||
| 1817 | # This was a ternary operation but they aren't supported in | |
| 1818 | # Minix's shell. | |
| 1819 | [ "${#line}" -gt "${ascii_width:-0}" ] &&
| |
| 1820 | ascii_width=${#line}
| |
| 1821 | ||
| 1822 | # Using '<<-EOF' is the only way to loop over a command's | |
| 1823 | # output without the use of a pipe ('|').
| |
| 1824 | # This ensures that any variables defined in the while loop | |
| 1825 | # are still accessible in the script. | |
| 1826 | done <<-EOF | |
| 1827 | $(printf %s "$ascii" | sed 's/\[3.m//g') | |
| 1828 | EOF | |
| 1829 | ||
| 1830 | # Add a gap between the ascii art and the information. | |
| 1831 | ascii_width=$((ascii_width + 4)) | |
| 1832 | ||
| 1833 | # Print the ascii art and position the cursor back where we | |
| 1834 | # started prior to printing it. | |
| 1835 | {
| |
| 1836 | esc_p SGR 1 | |
| 1837 | printf '%s' "$ascii" | |
| 1838 | esc_p SGR 0 | |
| 1839 | esc_p CUU "$ascii_height" | |
| 1840 | } >&6 | |
| 1841 | } | |
| 1842 | ||
| 1843 | main() {
| |
| 1844 | case $* in | |
| 1845 | -v) | |
| 1846 | printf '%s 0.7.0\n' "${0##*/}"
| |
| 1847 | return 0 | |
| 1848 | ;; | |
| 1849 | ||
| 1850 | -d) | |
| 1851 | # Below exec is not run, stderr is shown. | |
| 1852 | ;; | |
| 1853 | ||
| 1854 | '') | |
| 1855 | exec 2>/dev/null | |
| 1856 | ;; | |
| 1857 | ||
| 1858 | *) | |
| 1859 | cat < | |
| 1860 | ${0##*/} show system information
| |
| 1861 | ${0##*/} -d show stderr (debug mode)
| |
| 1862 | ${0##*/} -v show version information
| |
| 1863 | EOF | |
| 1864 | return 0 | |
| 1865 | ;; | |
| 1866 | esac | |
| 1867 | ||
| 1868 | # Hide 'stdout' and selectively print to it using '>&6'. | |
| 1869 | # This gives full control over what it displayed on the screen. | |
| 1870 | exec 6>&1 >/dev/null | |
| 1871 | ||
| 1872 | # Store raw escape sequence character for later reuse. | |
| 1873 | esc_c=$(printf '\033') | |
| 1874 | ||
| 1875 | # Allow the user to execute their own script and modify or | |
| 1876 | # extend pfetch's behavior. | |
| 1877 | # shellcheck source=/dev/null | |
| 1878 | ! [ -f "$PF_SOURCE" ] || . "$PF_SOURCE" | |
| 1879 | ||
| 1880 | # Ensure that the 'TMPDIR' is writable as heredocs use it and | |
| 1881 | # fail without the write permission. This was found to be the | |
| 1882 | # case on Android where the temporary directory requires root. | |
| 1883 | [ -w "${TMPDIR:-/tmp}" ] || export TMPDIR=~
| |
| 1884 | ||
| 1885 | # Generic color list. | |
| 1886 | # Disable warning about unused variables. | |
| 1887 | # shellcheck disable=2034 | |
| 1888 | for _c in c1 c2 c3 c4 c5 c6 c7 c8; do | |
| 1889 | esc SGR "3${_c#?}" 0
| |
| 1890 | export "$_c=$e" | |
| 1891 | done | |
| 1892 | ||
| 1893 | # Disable line wrapping and catch the EXIT signal to enable it again | |
| 1894 | # on exit. Ideally you'd somehow query the current value and retain | |
| 1895 | # it but I'm yet to see this irk anyone. | |
| 1896 | esc_p DECAWM l >&6 | |
| 1897 | trap 'esc_p DECAWM h >&6' EXIT | |
| 1898 | ||
| 1899 | # Store the output of 'uname' to avoid calling it multiple times | |
| 1900 | # throughout the script. 'read < | |
| 1901 | # a command into a list of variables. | |
| 1902 | read -r os kernel arch <<-EOF | |
| 1903 | $(uname -srm) | |
| 1904 | EOF | |
| 1905 | ||
| 1906 | # Always run 'get_os' for the purposes of detecting which ascii | |
| 1907 | # art to display. | |
| 1908 | get_os | |
| 1909 | ||
| 1910 | # Allow the user to specify the order and inclusion of information | |
| 1911 | # functions through the 'PF_INFO' environment variable. | |
| 1912 | # shellcheck disable=2086 | |
| 1913 | {
| |
| 1914 | # Disable globbing and set the positional parameters to the | |
| 1915 | # contents of 'PF_INFO'. | |
| 1916 | set -f | |
| 1917 | set +f -- ${PF_INFO-ascii title os host kernel uptime pkgs memory}
| |
| 1918 | ||
| 1919 | # Iterate over the info functions to determine the lengths of the | |
| 1920 | # "info names" for output alignment. The option names and subtitles | |
| 1921 | # match 1:1 so this is thankfully simple. | |
| 1922 | for info do | |
| 1923 | command -v "get_$info" >/dev/null || continue | |
| 1924 | ||
| 1925 | # This was a ternary operation but they aren't supported in | |
| 1926 | # Minix's shell. | |
| 1927 | [ "${#info}" -gt "${info_length:-0}" ] &&
| |
| 1928 | info_length=${#info}
| |
| 1929 | done | |
| 1930 | ||
| 1931 | # Add an additional space of length to act as a gap. | |
| 1932 | info_length=$((info_length + 1)) | |
| 1933 | ||
| 1934 | # Iterate over the above list and run any existing "get_" functions. | |
| 1935 | for info do | |
| 1936 | "get_$info" | |
| 1937 | done | |
| 1938 | } | |
| 1939 | ||
| 1940 | # Position the cursor below both the ascii art and information lines | |
| 1941 | # according to the height of both. If the information exceeds the ascii | |
| 1942 | # art in height, don't touch the cursor (0/unset), else move it down | |
| 1943 | # N lines. | |
| 1944 | # | |
| 1945 | # This was a ternary operation but they aren't supported in Minix's shell. | |
| 1946 | [ "${info_height:-0}" -lt "${ascii_height:-0}" ] &&
| |
| 1947 | cursor_pos=$((ascii_height - info_height)) | |
| 1948 | ||
| 1949 | # Print '$cursor_pos' amount of newlines to correctly position the | |
| 1950 | # cursor. This used to be a 'printf $(seq X X)' however 'seq' is only | |
| 1951 | # typically available (by default) on GNU based systems! | |
| 1952 | while [ "${i:=0}" -le "${cursor_pos:-0}" ]; do
| |
| 1953 | printf '\n' | |
| 1954 | i=$((i + 1)) | |
| 1955 | done >&6 | |
| 1956 | } | |
| 1957 |
