98 Commits
term ... 0.4.0

Author SHA1 Message Date
Dylan Araps
8b9c409650 macOS: fix memory issue 2019-10-03 21:06:51 +03:00
Dylan Araps
52617b2e6e arch: new logo 2019-10-03 18:34:32 +03:00
Dylan Araps
77dce6a678 freebsd: better ascii 2019-10-03 13:59:36 +03:00
Dylan Araps
812f9ef231 docs: update 2019-10-03 12:30:25 +03:00
Dylan Araps
87effdbc5a host: add another dummy word 2019-10-03 12:29:31 +03:00
Dylan Araps
3f5845e20c pfetch: android support 2019-10-03 10:18:34 +03:00
Dylan Araps
c94e2c5d9d wm: handle non-matches 2019-10-02 15:36:09 +03:00
Dylan Araps
d8d8899ad2 macOS: Fix port false positive 2019-10-01 23:24:26 +03:00
Dylan Araps
1ff17055b9 pfetch: fix bug 2019-10-01 15:09:43 +03:00
Dylan Araps
d1d3b7b740 pfetch: fix bug 2019-10-01 15:07:50 +03:00
Dylan Araps
9564246e6c pfetch: fix bug 2019-10-01 15:06:37 +03:00
Dylan Araps
08d9834854 pfetch: fix bug 2019-10-01 15:05:42 +03:00
Dylan Araps
b7c7bc6c4c pfetch: fix bug 2019-10-01 15:03:56 +03:00
Dylan Araps
11d1c2e789 docs: update 2019-10-01 11:19:52 +03:00
Dylan Araps
55408239db docs: update 2019-10-01 11:19:32 +03:00
Dylan Araps
35ae795068 docs: update 2019-10-01 11:18:59 +03:00
Dylan Araps
e1228975fd docs: update 2019-10-01 11:17:57 +03:00
Dylan Araps
4d1be75c20 docs: update 2019-10-01 11:13:45 +03:00
Dylan Araps
8d1ab2d0dd docs: update 2019-10-01 11:13:13 +03:00
Dylan Araps
301c52dd5f docs: update 2019-10-01 11:12:55 +03:00
Dylan Araps
0d1a340ef2 docs: update 2019-10-01 11:12:16 +03:00
Dylan Araps
49a3db1653 docs: update 2019-10-01 11:03:39 +03:00
Dylan Araps
d828d1e718 docs: update 2019-10-01 11:02:48 +03:00
Dylan Araps
9963de75d5 docs: update 2019-10-01 11:02:31 +03:00
Dylan Araps
3e58031fe0 docs: update 2019-10-01 11:01:38 +03:00
Dylan Araps
405fc20eef docs: update 2019-10-01 11:00:58 +03:00
Dylan Araps
133d63137c docs: update 2019-10-01 11:00:01 +03:00
Dylan Araps
3686c06238 docs: update 2019-10-01 10:59:35 +03:00
Dylan Araps
c20823937c pfetch: added Android ascii 2019-10-01 09:50:08 +03:00
Dylan Araps
177f30b72f docs: update 2019-10-01 09:27:58 +03:00
Dylan Araps
aea34f832c docs: update 2019-10-01 02:01:10 +03:00
Dylan Araps
6829866ba9 docs: update 2019-10-01 02:00:36 +03:00
Dylan Araps
f7180ec8a7 docs: update 2019-10-01 01:59:01 +03:00
Dylan Araps
777a64b4b1 docs: update 2019-10-01 01:58:16 +03:00
Dylan Araps
765dc077e7 docs: update 2019-10-01 01:55:53 +03:00
Dylan Araps
2e3da189ca pfetch: smarter terminal sequence handling 2019-10-01 01:52:32 +03:00
Dylan Araps
344086b464 github: check st-256color value 2019-10-01 01:38:19 +03:00
Dylan Araps
e0b082423f github: abuse CI to test escape sequence detection 2019-10-01 01:06:07 +03:00
Dylan Araps
66e0bfe709 github: abuse CI to test escape sequence detection 2019-10-01 01:05:17 +03:00
Dylan Araps
c97120b82f docs: update 2019-10-01 00:54:16 +03:00
Dylan Araps
46b68022a3 pfetch: Simpler WSL2 detection. 2019-10-01 00:49:54 +03:00
Dylan Araps
146c6b6bae pfetch: Fix WSL2 detection. 2019-10-01 00:44:22 +03:00
Dylan Araps
d8becf6692 docs: update 2019-10-01 00:19:33 +03:00
Dylan Araps
887df06b6a pfetch: wm support for Xorg 2019-10-01 00:18:58 +03:00
Dylan Araps
a6b4b085fb docs: update 2019-10-01 00:00:27 +03:00
Dylan Araps
cfc0e8e4d0 docs: update 2019-09-30 23:55:57 +03:00
Dylan Araps
29b09c8622 pfetch: de and editor support 2019-09-30 23:53:25 +03:00
Dylan Araps
6c2ffdd07e docs: update 2019-09-30 23:38:24 +03:00
Dylan Araps
8974dad27a docs: update 2019-09-30 23:37:36 +03:00
Dylan Araps
9442360c09 docs: update 2019-09-30 23:20:07 +03:00
Dylan Araps
ee265316d9 docs: update 2019-09-30 23:19:27 +03:00
Dylan Araps
442a2ba217 docs: update 2019-09-30 23:18:56 +03:00
Dylan Araps
120e8a8760 docs: update 2019-09-30 23:16:03 +03:00
Dylan Araps
d706ec7a01 docs: update 2019-09-30 23:01:36 +03:00
Dylan Araps
c9d961836c solaris: comments 2019-09-30 20:08:27 +03:00
dylan
3a8ac8c53d Merge pull request #18 from Crestwave/solaris
pfetch: initial solaris support
2019-09-30 20:05:49 +03:00
Dylan Araps
fcd62e9043 better os-release handling, and sunos ascii 2019-09-30 20:02:36 +03:00
Crestwave
02a9bd84af pfetch: code style changes 2019-09-30 15:32:54 +08:00
Crestwave
a9af270b96 pfetch: initial solaris support 2019-09-30 15:18:09 +08:00
Dylan Araps
9985e6cfe9 pfetch: fix whoami not posix 2019-09-30 09:25:39 +03:00
Dylan Araps
0977e5f1a1 docs: update 2019-09-29 17:25:26 +03:00
Dylan Araps
8ff9d722b5 memory: netBSD fix 2019-09-29 16:59:08 +03:00
Dylan Araps
ca4004de90 uptime: bug fix 2019-09-29 16:28:43 +03:00
Dylan Araps
ee6e1bd390 memory: bug fix 2019-09-29 16:27:45 +03:00
Dylan Araps
c888f4cdca pfetch: fix dragonfly issues 2019-09-29 16:20:16 +03:00
Dylan Araps
1363a973d4 misc: clean up 2019-09-29 13:20:27 +03:00
Dylan Araps
7e70668ce7 kiss: faster package list' 2019-09-29 12:24:18 +03:00
Dylan Araps
935fd295dd docs: update 2019-09-29 12:21:16 +03:00
Dylan Araps
5648839b55 pfetch: Ubuntu support 2019-09-29 12:21:07 +03:00
Dylan Araps
d79c2f20d5 docs: update 2019-09-29 11:46:15 +03:00
Dylan Araps
24e063479a docs: update 2019-09-29 09:32:42 +03:00
Dylan Araps
3a562917c3 pfetch: initial DragonflyBSD support 2019-09-29 09:19:35 +03:00
Dylan Araps
300f31c5cd memory: fix issue in yash 2019-09-28 17:18:18 +03:00
Dylan Araps
f4bb7a3da8 pfetch: initial dragonfly support 2019-09-28 16:50:49 +03:00
Dylan Araps
09c179f6f5 docs: update 2019-09-28 15:56:13 +03:00
Dylan Araps
b85ec5657d docs: update 2019-09-28 15:04:05 +03:00
Dylan Araps
6b46e941cd fix more minixisms 2019-09-28 15:02:44 +03:00
Dylan Araps
180c00173a fix more minixisms 2019-09-28 15:00:45 +03:00
Dylan Araps
be6b5ae5ed minix's sh requires all variables have default values 2019-09-28 14:56:12 +03:00
Dylan Araps
c6f46d5428 pfetch: portability with minix 2019-09-28 14:49:34 +03:00
Dylan Araps
a43a697551 fix arithmetic in minix 2019-09-28 14:41:57 +03:00
Dylan Araps
8b801b8b50 pfetch: minix support 2019-09-28 14:31:10 +03:00
Dylan Araps
c9c27ba54b initial minux support 2019-09-28 13:11:49 +03:00
Dylan Araps
090fe64dec guix: simpler package list 2019-09-28 12:57:23 +03:00
Dylan Araps
fddfe5435c docs: update 2019-09-28 12:21:36 +03:00
Dylan Araps
a7d1a6d980 docs: update 2019-09-28 12:20:15 +03:00
Dylan Araps
6c50390f78 docs: update 2019-09-28 12:16:51 +03:00
Dylan Araps
ec69fcb195 docs: update 2019-09-28 12:13:16 +03:00
Dylan Araps
599db8dc83 docs: update 2019-09-28 12:12:20 +03:00
Dylan Araps
7d343f9d62 haiku: comment 2019-09-28 11:51:40 +03:00
Dylan Araps
1b37bf9dd2 docs: update 2019-09-28 10:32:41 +03:00
Dylan Araps
eb9c8a3cfe pfetch: WSL support 2019-09-28 10:30:59 +03:00
Dylan Araps
59340ff4ce pkgs: fix extra count 2019-09-28 07:25:20 +03:00
Dylan Araps
68d2422a1b os: fixed lsb_release, closes #14 2019-09-28 07:01:50 +03:00
Dylan Araps
55b78b9e58 docs: update 2019-09-27 22:45:16 +03:00
Dylan Araps
b7292e0cbc docs: update 2019-09-27 22:03:34 +03:00
Dylan Araps
ba03cb3cf4 pfetch: add get_palette 2019-09-27 21:49:44 +03:00
Dylan Araps
d91cd1c0bf docs: update 2019-09-27 21:04:00 +03:00
3 changed files with 474 additions and 131 deletions

View File

@@ -6,4 +6,6 @@ jobs:
steps:
- uses: actions/checkout@v1
- name: Run shellcheck.
run: shellcheck pfetch
run: |
shellcheck pfetch
TERM=dumb sh pfetch

View File

@@ -1,52 +1,42 @@
# pfetch
<p align="center"><img src="https://user-images.githubusercontent.com/6799467/65944518-68834d80-e421-11e9-9b14-6ca26a16108a.png" width="350px"></p>
<h1 align="center">pfetch</h1>
<p align="center">A pretty system information tool written in POSIX sh</p><br>
A pretty system information tool written in POSIX `sh`.
<img src="https://user-images.githubusercontent.com/6799467/65945384-5bfff480-e423-11e9-863e-4e7cf16eb648.png" width="40%" align="right">
The goal of this project is to implement a simple system information tool in POSIX `sh` using features built into the language itself (*where possible*).
The goal of this project is to implement a simple system
information tool in POSIX `sh` using features built into
the language itself (*where possible*).
The source code is highly documented and I hope it will act as a learning resource for POSIX `sh` and simple information detection across various different operating systems.
The source code is highly documented and I hope it will
act as a learning resource for POSIX `sh` and simple
information detection across various different operating
systems.
If anything in the source code is unclear or is lacking in its explanation, open an issue. Sometimes you get too close to something and you fail to see the "bigger picture"!
If anything in the source code is unclear or is lacking
in its explanation, open an issue. Sometimes you get too
close to something and you fail to see the "bigger
picture"!
```sh
➜ pfetch
___ goldie@KISS
(| os KISS Linux
(<> | host Lenovo YOGA 900-13ISK
/ __ \ kernel 5.3.1-coffee
( / \ /| uptime 6h 20m
_/\ __)/_) pkgs 130
\/-____\/ memory 1721M / 7942M
```
<br>
<br>
<br>
<br>
## OS support
- [x] Linux (A myriad of distributions)
- [x] MacOS
- [x] OpenBSD
- [x] FreeBSD
- [x] NetBSD
- [x] Haiku
## TODO
- [ ] Add optional and additional information detection.
- [ ] CPU
- [ ] Terminal Emulator
- The way I implement this in `neofetch` is interesting.
- [ ] Terminal colors
- [ ] ???
- [ ] Expand operating system support.
- [ ] Solaris ([#5](https://github.com/dylanaraps/pfetch/issues/5))
- [ ] MINIX ([#6](https://github.com/dylanaraps/pfetch/issues/6))
- [ ] AIX ([#7](https://github.com/dylanaraps/pfetch/issues/7))
- [ ] IRIX ([#8](https://github.com/dylanaraps/pfetch/issues/8))
- [ ] FreeMiNT ([#9](https://github.com/dylanaraps/pfetch/issues/9))
- [ ] Windows ([#10](https://github.com/dylanaraps/pfetch/issues/10))
- [ ] CYGWIN
- [ ] MSYS
- [ ] MINGW
- [ ] WSL (*this is fairly simple*)
- **Linux**
- Alpine Linux, Arch Linux, Arco Linux, Artix Linux, CentOS, Debian, Elementary, Fedora, Gentoo, Guix, Hyperbola, KISS Linux, Linux Lite, Linux Mint, Mageia, Manjaro, MX Linux, NixOS, OpenSUSE, Parabola, Pop!\_OS, PureOS, Slackware, Ubuntu and Void Linux.
- All other distributions are supported with a generic penguin logo.
- **Android**
- **BSD**
- DragonflyBSD, FreeBSD, NetBSD and OpenBSD.
- **Windows**
- Windows subsystem for Linux.
- **Haiku**
- **MacOS**
- **Minix**
- **Solaris**
## Configuration
@@ -58,14 +48,14 @@ _/\ __)/_) pkgs 130
# Default: first example below
# Valid: space separated string
#
# OFF by default: shell
PF_INFO="ascii title distro host kernel uptime pkgs memory"
# OFF by default: shell editor wm de palette
PF_INFO="ascii title os host kernel uptime pkgs memory"
# Example: Only ASCII.
PF_INFO="ascii"
# Example: Only Information.
PF_INFO="title distro host kernel uptime pkgs memory"
PF_INFO="title os host kernel uptime pkgs memory"
# Separator between info name and info data.
# Default: unset
@@ -96,6 +86,26 @@ PF_ALIGN=""
# Default: unset (auto)
# Valid: string
PF_ASCII="openbsd"
# The below environment variables control more
# than just 'pfetch' and can be passed using
# 'HOSTNAME=cool_pc pfetch' to restrict their
# usage solely to 'pfetch'.
# Which user to display.
USER=""
# Which hostname to display.
HOSTNAME=""
# Which editor to display.
EDITOR=""
# Which shell to display.
SHELL=""
# Which desktop environment to display.
XDG_CURRENT_DESKTOP=""
```
## Credit

503
pfetch
View File

@@ -64,7 +64,7 @@ log() {
# Use 'set --' as a means of stripping all leading and trailing
# white-space from the info string. This also normalizes all
# whitespace inside of the string.
# white-space inside of the string.
#
# Disable the shellcheck warning for word-splitting
# as it's safe and intended ('set -f' disables globbing).
@@ -95,13 +95,13 @@ log() {
printf '[3%sm%s\n' "${PF_COL2-7}" "$info"
# Keep track of the number of times 'log()' has been run.
: $((info_height+=1))
info_height=$((${info_height:-0} + 1))
}
get_title() {
# Username is retrieved by first checking '$USER' with a fallback
# to the 'whoami' command.
user=${USER:-$(whoami)}
# to the 'id -un' command.
user=${USER:-$(id -un)}
# Hostname is retrieved by first checking '$HOSTNAME' with a fallback
# to the 'hostname' command.
@@ -129,7 +129,7 @@ get_os() {
case $os in
Linux*)
# Some Linux disttributions (which are based on others)
# Some Linux distributions (which are based on others)
# fail to identify as they **do not** change the upstream
# distributions identification packages or files.
#
@@ -154,17 +154,51 @@ get_os() {
if command -v lsb_release; then
distro=$(lsb_release -sd)
# Android detection works by checking for the existence of
# the follow two directories. I don't think there's a simpler
# method than this.
elif [ -d /system/app ] && [ -d /system/priv-app ]; then
distro="Android $(getprop ro.build.version.release)"
else
# Disable warning about shellcheck not being able
# to read '/etc/os-release'. This is fine.
# shellcheck source=/dev/null
. /etc/os-release && distro=$PRETTY_NAME
# This used to be a simple '. /etc/os-release' but I believe
# this is insecure as we blindly executed whatever was in the
# file. This parser instead simply handles 'key=val', treating
# the file contents as plain-text.
while IFS='=' read -r key val; do
case $key in
PRETTY_NAME) distro=$val ;;
esac
done < /etc/os-release
fi
# 'os-release' and 'lsb_release' sometimes add quotes
# around the distribution name, strip them.
distro=${distro##[\"\']}
distro=${distro%%[\"\']}
# Special cases for (independent) distributions which
# don't follow any os-release/lsb standards whatsoever.
command -v crux && distro=$(crux)
command -v guix && distro='Guix System'
command -v crux && distro=$(crux)
command -v guix && distro='Guix System'
# Check to see if Linux is running in Windows 10 under
# WSL1 (Windows subsystem for Linux [version 1]) and
# append a string accordingly.
#
# If the kernel version string ends in "-Microsoft",
# we're very likely running under Windows 10 in WSL1.
[ "${kernel%%*-Microsoft}" ] ||
distro="$distro on Windows 10 [WSL1]"
# Check to see if Linux is running in Windows 10 under
# WSL2 (Windows subsystem for Linux [version 2]) and
# append a string accordingly.
#
# This checks to see if '$WSLENV' is defined. This
# appends the Windows 10 string even if '$WSLENV' is
# empty. We only need to check that is has been _exported_.
distro="${distro}${WSLENV+ on Windows 10 [WSL2]}"
;;
Darwin*)
@@ -215,8 +249,22 @@ get_os() {
Haiku)
# Haiku uses 'uname -v' for version information
# instead of 'uname -r'.
distro="Haiku $(uname -v)"
# instead of 'uname -r' which only prints '1'.
distro=$(uname -sv)
;;
Minix|DragonFly)
distro="$os $kernel"
# Minix and DragonFly don't support the escape
# sequences used, clear the exit trap.
trap '' EXIT
;;
SunOS)
# Grab the first line of the '/etc/release' file
# discarding everything after '('.
IFS='(' read -r distro _ < /etc/release
;;
*)
@@ -231,7 +279,7 @@ get_kernel() {
case $os in
# Don't print kernel output on some systems as the
# OS name includes it.
*BSD*|Haiku) ;;
*BSD*|Haiku|Minix) ;;
*)
# '$kernel' is the cached output of 'uname -r'.
@@ -240,10 +288,6 @@ get_kernel() {
esac
}
get_shell() {
log shell "${SHELL##*/}" >&6
}
get_host() {
case $os in
Linux*)
@@ -257,7 +301,7 @@ get_host() {
host="$name $version $model"
;;
Darwin*|FreeBSD*)
Darwin*|FreeBSD*|DragonFly*)
host=$(sysctl -n hw.model)
;;
@@ -301,7 +345,7 @@ get_host() {
case $word in
To | [Bb]e | [Ff]illed | by | O.E.M. | OEM |\
Not | Applicable | Specified | System | Product | Name |\
Version | Undefined | Default | string | INVALID | <20> )
Version | Undefined | Default | string | INVALID | <20> | os )
continue
;;
esac
@@ -318,11 +362,11 @@ get_uptime() {
# converting that data into days, hours and minutes using simple
# math.
case $os in
Linux*)
Linux*|Minix*)
IFS=. read -r s _ < /proc/uptime
;;
Darwin*|*BSD*)
Darwin*|*BSD*|DragonFly*)
s=$(sysctl -n kern.boottime)
# Extract the uptime in seconds from the following output:
@@ -340,6 +384,19 @@ get_uptime() {
# regular seconds.
s=$(($(system_time) / 1000000))
;;
SunOS)
# Split the output of 'kstat' on '.' and any white-space
# which exists in the command output.
#
# The output is as follows:
# unix:0:system_misc:snaptime 14809.906993005
#
# The parser extracts: ^^^^^
IFS=' .' read -r _ s _ <<-EOF
$(kstat -p unix:0:system_misc:snaptime)
EOF
;;
esac
# Convert the uptime from seconds into days, hours and minutes.
@@ -356,6 +413,10 @@ get_uptime() {
}
get_pkgs() {
# This is just a simple wrapper around 'command -v' to avoid
# spamming '>/dev/null' throughout this function.
has() { command -v "$1" >/dev/null; }
# This works by first checking for which package managers are
# installed and finally by printing each package manager's
# package list with each package one per line.
@@ -376,27 +437,22 @@ get_pkgs() {
case $os in
Linux*)
# Commands which print packages one per line.
command -v kiss && kiss l
command -v bonsai && bonsai list
command -v pacman-key && pacman -Qq
command -v dpkg && dpkg-query -f '.\n' -W
command -v rpm && rpm -qa
command -v xbps-query && xbps-query -l
command -v apk && apk info
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
has guix && guix package --list-installed
# Directories containing packages.
command -v brew && printf '%s\n' "$(brew --cellar)/"*
command -v emerge && printf '%s\n' /var/db/pkg/*/*/
command -v pkgtool && printf '%s\n' /var/log/packages/*
has kiss && printf '%s\n' /var/db/kiss/installed/*/
has brew && printf '%s\n' "$(brew --cellar)/"*
has emerge && printf '%s\n' /var/db/pkg/*/*/
has pkgtool && printf '%s\n' /var/log/packages/*
# GUIX requires two commands.
command -v guix && {
guix package -p /run/current-system/profile -I
guix package -I
}
# NIX requires two commands.
command -v nix-store && {
# 'nix' requires two commands.
has nix-store && {
nix-store -q --requisites /run/current-system/sw
nix-store -q --requisites ~.nix-profile
}
@@ -404,14 +460,28 @@ get_pkgs() {
Darwin*)
# Commands which print packages one per line.
command -v pkgin && pkgin list
command -v port && port installed
has pkgin && pkgin list
# Directories containing packages.
command -v brew && printf '%s\n' /usr/local/Cellar/*
has brew && printf '%s\n' /usr/local/Cellar/*
# 'port' prints a single line of output to 'stdout'
# when no packages are installed and exits with
# success causing a false-positive of 1 package
# installed.
#
# 'port' should really exit with a non-zero code
# in this case to allow scripts to cleanly handle
# this behavior.
has port && {
pkg_list=$(port installed)
[ "$pkg_list" = "No ports are installed." ] ||
printf '%s\n' "$pkg_list"
}
;;
FreeBSD*)
FreeBSD*|DragonFly*)
pkg info
;;
@@ -426,6 +496,15 @@ get_pkgs() {
Haiku)
printf '%s\n' /boot/system/package-links/*
;;
Minix)
printf '%s\n' /usr/pkg/var/db/pkg/*/
;;
SunOS)
has pkginfo && pkginfo -i
has pkg && pkg list
;;
esac | wc -l
`
@@ -434,14 +513,14 @@ get_pkgs() {
get_memory() {
case $os in
# Used memory is calculated using the following "formula" (Linux):
# Used memory is calculated using the following "formula":
# MemUsed = MemTotal + Shmem - MemFree - Buffers - Cached - SReclaimable
# Source: https://github.com/KittyKatt/screenFetch/issues/386
Linux*)
# Parse the '/proc/meminfo' file splitting on ':' and 'k'.
# The format of the file is 'key: 000kB' and an additional
# split is used on 'k' to filter out 'kB'.
while IFS=:k read -r key val _; do
while IFS=':k ' read -r key val _; do
case $key in
MemTotal)
mem_used=$((mem_used + val))
@@ -462,7 +541,7 @@ get_memory() {
mem_full=$((mem_full / 1024))
;;
# Used memory is calculated using the following "formula" (MacOS):
# Used memory is calculated using the following "formula":
# (wired + active + occupied) * 4 / 1024
Darwin*)
mem_full=$(($(sysctl -n hw.memsize) / 1024 / 1024))
@@ -472,7 +551,7 @@ get_memory() {
# split is used on '.' to filter it out.
while IFS=:. read -r key val; do
case $key in
*wired*|*active*|*occupied*)
*' wired'*|*' active'*|*' occupied'*)
mem_used=$((mem_used + ${val:-0}))
;;
esac
@@ -512,9 +591,9 @@ get_memory() {
EOF
;;
# Used memory is calculated using the following "formula" (FreeBSD):
# (inactive_count + free_count + cache_count) * page_size / 1024
FreeBSD*)
# Used memory is calculated using the following "formula":
# mem_full - ((inactive + free + cache) * page_size / 1024)
FreeBSD*|DragonFly*)
mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024))
# Use 'set --' to store the output of the command in the
@@ -536,7 +615,7 @@ get_memory() {
# $2: vm.stats.vm.v_inactive_count
# $3: vm.stats.vm.v_free_count
# $4: vm.stats.vm.v_cache_count
mem_used=$((($2 + $3 + $4) * $1 / 1024 / 1024))
mem_used=$((mem_full - (($2 + $3 + $4) * $1 / 1024 / 1024)))
;;
NetBSD*)
@@ -544,7 +623,7 @@ get_memory() {
# NetBSD implements a lot of the Linux '/proc' filesystem,
# this uses the same parser as the Linux memory detection.
while IFS=:k read -r key val _; do
while IFS=':k ' read -r key val _; do
case $key in
MemFree)
mem_free=$((val / 1024))
@@ -571,11 +650,182 @@ get_memory() {
mem_used=$((mem_used / 1024 / 1024))
mem_full=$((mem_full / 1024 / 1024))
;;
Minix)
# Minix includes the '/proc' filesystem though the format
# differs from Linux. The '/proc/meminfo' file is only a
# single line with space separated elements and elements
# 2 and 3 contain the total and free memory numbers.
read -r _ mem_full mem_free _ < /proc/meminfo
mem_used=$(((mem_full - mem_free) / 1024))
mem_full=$(( mem_full / 1024))
;;
SunOS)
hw_pagesize=$(pagesize)
# 'kstat' outputs memory in the following format:
# unix:0:system_pages:pagestotal 1046397
# unix:0:system_pages:pagesfree 885018
#
# This simply uses the first "element" (white-space
# separated) as the key and the second element as the
# value.
#
# A variable is then assigned based on the key.
while read -r key val; do
case $key in
*total) pages_full=$val ;;
*free) pages_free=$val ;;
esac
done <<-EOF
$(kstat -p unix:0:system_pages:pagestotal \
unix:0:system_pages:pagesfree)
EOF
mem_full=$((pages_full * hw_pagesize / 1024 / 1024))
mem_free=$((pages_free * hw_pagesize / 1024 / 1024))
mem_used=$((mem_full - mem_free))
;;
esac
log memory "${mem_used:-?}M / ${mem_full:-?}M" >&6
}
get_wm() {
case $os in
# Don't display window manager on macOS.
Darwin*) ;;
*)
# xprop can be used to grab the window manager's properties
# which contains the window manager's name under '_NET_WM_NAME'.
#
# The upside to using 'xprop' is that you don't need to hardcode
# a list of known window manager names. The downside is that
# not all window managers conform to setting the '_NET_WM_NAME'
# atom..
#
# List of window managers which fail to set the name atom:
# catwm, fvwm, dwm, 2bwm and monster.
#
# The final downside to this approach is that it does _not_
# support Wayland environments. The only solution which supports
# Wayland is the 'ps' parsing mentioned below.
#
# A more naive implementation is to parse the last line of
# '~/.xinitrc' to extract the second white-space separated
# element.
#
# The issue with an approach like this is that this line data
# does not always equate to the name of the window manager and
# could in theory be _anything_.
#
# This also fails when the user launches xorg through a display
# manager or other means.
#
#
# Another naive solution is to parse 'ps' with a hardcoded list
# of window managers to detect the current window manager (based
# on what is running).
#
# The issue with this approach is the need to hardcode and
# maintain a list of known window managers.
#
# Another issue is that process names do not always equate to
# the name of the window manager. False-positives can happen too.
#
# This is the only solution which supports Wayland based
# environments sadly. It'd be nice if some kind of standard were
# established to identify Wayland environments.
#
# pfetch's goal is to remain _simple_, if you'd like a "full"
# implementation of window manager detection use 'neofetch'.
#
# Neofetch use a combination of 'xprop' and 'ps' parsing to
# support all window managers (including non-conforming and
# Wayland) though it's a lot more complicated!
# Don't display window manager if X isn't running.
[ "$DISPLAY" ] || return
# This is a two pass call to xprop. One call to get the window
# manager's ID and another to print its properties.
command -v xprop && {
# The output of the ID command is as follows:
# _NET_SUPPORTING_WM_CHECK: window id # 0x400000
#
# To extract the ID, everything before the last space
# is removed.
id=$(xprop -root -notype _NET_SUPPORTING_WM_CHECK)
id=${id##* }
# The output of the property command is as follows:
# _NAME 8t
# _NET_WM_PID = 252
# _NET_WM_NAME = "bspwm"
# _NET_SUPPORTING_WM_CHECK: window id # 0x400000
# WM_CLASS = "wm", "Bspwm"
#
# To extract the name, everything before '_NET_WM_NAME = \"'
# is removed and everything after the next '"' is removed.
wm=$(xprop -id "$id" -notype -len 25 -f _NET_WM_NAME 8t)
# Handle cases of a window manager _not_ populating the
# '_NET_WM_NAME' atom. Display nothing in this case.
case $wm in
*'_NET_WM_NAME = '*)
wm=${wm##*_NET_WM_NAME = \"}
wm=${wm%%\"*}
;;
*) wm= ;;
esac
}
;;
esac
log wm "$wm" >&6
}
get_de() {
# This only supports Xorg related desktop environments though
# this is fine as knowing the desktop envrionment on Windows,
# macOS etc is useless (they'll always report the same value).
#
# Display the value of '$XDG_CURRENT_DESKTOP', if it's empty,
# display the value of '$DESKTOP_SESSION'.
log de "${XDG_CURRENT_DESKTOP:-$DESKTOP_SESSION}" >&6
}
get_shell() {
# Display the basename of the '$SHELL' environment variable.
log shell "${SHELL##*/}" >&6
}
get_editor() {
# Display the value of '$VISUAL', if it's empty, display the
# value of '$EDITOR'.
log editor "${VISUAL:-$EDITOR}" >&6
}
get_palette() {
# Print the first 8 terminal colors. This uses the existing
# sequences to change text color with a sequence prepended
# to reverse the foreground and background colors.
#
# This allows us to save hardcoding a second set of sequences
# for background colors.
palette=" $c1 $c2 $c3 $c4 $c5 $c6 $c7 "
# Print the palette with a newline before and after.
# The '\033[%sC' moves the text to the right, the
# length of the ascii art.
printf '\n[%sC%s\n' "${ascii_width-1}" "$palette" >&6
}
get_ascii() {
# This is a simple function to read the contents of
# an ascii file from 'stdin'. It allows for the use
@@ -624,15 +874,26 @@ get_ascii() {
EOF
;;
[Aa]ndroid*)
read_ascii 2 <<-EOF
${c2} ;, ,;
';,.-----.,;'
,' ',
/ O O \\
| |
'-----------------'
EOF
;;
[Aa]rch*)
read_ascii 4 <<-EOF
${c6} /\\
/^^\\
/\\ \\
/${c7} __ \\
/ ( ) \\
/ __| |__\\\\
/// \\\\\\
${c6} /\\
/ \\
/\\ \\
${c4} / \\
/ ,, \\
/ | | -\\
/_-'' ''-_\\
EOF
;;
@@ -683,6 +944,18 @@ get_ascii() {
EOF
;;
[Dd]ragon[Ff]ly*)
read_ascii 1 <<-EOF
,${c1}_${c7},
('-_${c1}|${c7}_-')
>--${c1}|${c7}--<
(_-'${c1}|${c7}'-_)
${c1}|
|
|
EOF
;;
[Ee]lementary*)
read_ascii <<-EOF
${c7} _______
@@ -709,13 +982,12 @@ get_ascii() {
[Ff]ree[Bb][Ss][Dd]*)
read_ascii 1 <<-EOF
${c1} /\\ _____ /\\
\\_) (_/
/ \\
${c1}/\\,-'''''-,/\\
\\_) (_/
| |
| |
\ /
--_____--
; ;
'-_____-'
EOF
;;
@@ -731,7 +1003,7 @@ get_ascii() {
EOF
;;
[Gg]uix[Ss][Dd]*|guix*)
[Gg]uix[Ss][Dd]*|[Gg]uix*)
read_ascii 3 <<-EOF
${c3}|.__ __.|
|__ \\ / __|
@@ -768,7 +1040,7 @@ get_ascii() {
EOF
;;
[Ll]inux*[Ll]ite*)
[Ll]inux*[Ll]ite*|[Ll]ite*)
read_ascii 3 <<-EOF
${c3} /\\
/ \\
@@ -841,6 +1113,19 @@ get_ascii() {
EOF
;;
[Mm]inix*)
read_ascii 4 <<-EOF
${c4} ,, ,,
;${c7},${c4} ', ,' ${c7},${c4};
; ${c7}',${c4} ',,' ${c7},'${c4} ;
; ${c7}',${c4} ${c7},'${c4} ;
; ${c7};, '' ,;${c4} ;
; ${c7};${c4};${c7}',,'${c4};${c7};${c4} ;
', ${c7};${c4};; ;;${c7};${c4} ,'
'${c7};${c4}' '${c7};${c4}'
EOF
;;
[Mm][Xx]*)
read_ascii <<-EOF
${c7} \\\\ /
@@ -889,7 +1174,7 @@ get_ascii() {
EOF
;;
openSUSE*|open*SUSE*|SUSE*|suse*)
[Oo]penSUSE*|[Oo]pen*SUSE*|SUSE*|suse*)
read_ascii 2 <<-EOF
${c2} _______
__| __ \\
@@ -948,6 +1233,27 @@ get_ascii() {
EOF
;;
[Ss]un[Oo][Ss]|[Ss]olaris*)
read_ascii 3 <<-EOF
${c3} . .; .
. :; :: ;: .
.;. .. .. .;.
.. .. .. ..
.;, ,;.
EOF
;;
[Uu]buntu*)
read_ascii 3 <<-EOF
${c3} _
---(_)
_/ --- \\
(_) | |
\\ --- _/
---(_)
EOF
;;
[Vv]oid*)
read_ascii 2 <<-EOF
${c2} _______
@@ -984,8 +1290,12 @@ get_ascii() {
# information. The 'sed' is used to strip 'm' color codes from
# the ascii art so they don't affect the width variable.
while read -r line; do
: $((ascii_height+=1))
ascii_width=$((${#line} > ascii_width ? ${#line} : ascii_width))
ascii_height=$((${ascii_height:-0} + 1))
# This was a ternary operation but they aren't supported in
# Minix's shell.
[ "${#line}" -gt "${ascii_width:-0}" ] &&
ascii_width=${#line}
# Using '<<-EOF' is the only way to loop over a command's
# output without the use of a pipe ('|').
@@ -996,24 +1306,17 @@ get_ascii() {
EOF
# Add a gap between the ascii art and the information.
: $((ascii_width+=4))
ascii_width=$((ascii_width + 4))
# Print the ascii art and position the cursor back where we
# started prior to printing it.
# '[?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%s[%sA' "$ascii" "$ascii_height" >&6
printf '%s[%sA' "$ascii" "$ascii_height" >&6
}
main() {
# 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 >&6' EXIT
# Hide 'stderr' unless the first argument is '-v'. This saves
# polluting the script with '2>/dev/null'.
[ "$1" = -v ] || exec 2>/dev/null
@@ -1032,6 +1335,26 @@ main() {
c7=''; c8=''
}
# Avoid text-wrapping from wrecking the program output
# and hide the cursor to hide its moving around during
# the printing process.
#
# Some terminals don't support these sequences, nor do they
# silently conceal them if they're printed resulting in
# partial sequences being printed to the terminal!
[ "$TERM" = dumb ] ||
[ "$TERM" = minix ] ||
[ "$TERM" = cons25 ] || {
# '[?7l': Disable line-wrapping.
# '[?25l': Hide the cursor.
printf '[?7l[?25l' >&6
# Leave the terminal how we found it on exit or Ctrl+C.
# '[?7h': Enable line-wrapping.
# '[?25h': Show the cursor.
trap 'printf [?7h[?25h >&6' EXIT
}
# Store the output of 'uname' to avoid calling it multiple times
# throughout the script. 'read <<EOF' is the simplest way of reading
# a command into a list of variables.
@@ -1056,12 +1379,16 @@ main() {
# "info names" for output alignment. The option names and subtitles
# match 1:1 so this is thankfully simple.
for info; do
command -v "get_$info" >/dev/null &&
info_length=$((${#info} > info_length ? ${#info} : info_length))
command -v "get_$info" >/dev/null || continue
# This was a ternary operation but they aren't supported in
# Minix's shell.
[ "${#info}" -gt "${info_length:-0}" ] &&
info_length=${#info}
done
# Add an additional space of length to act as a gap.
: $((info_length+=1))
info_length=$((info_length + 1))
# Iterate over the above list and run any existing "get_" functions.
for info; do "get_$info"; done
@@ -1069,15 +1396,19 @@ main() {
# 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.
cursor_pos=$((info_height > ascii_height ? 0 : ascii_height - info_height))
# art in height, don't touch the cursor (0/unset), else move it down
# N lines.
#
# This was a ternary operation but they aren't supported in Minix's shell.
[ "${info_height:-0}" -lt "${ascii_height:-0}" ] &&
cursor_pos=$((ascii_height - info_height))
# Print '$cursor_pos' amount of newlines to correctly position the
# cursor. This used to be a 'printf $(seq X X)' however 'seq' is only
# typically available (by default) on GNU based systems!
while [ "${i:-0}" -le "$cursor_pos" ]; do
while [ "${i:=0}" -le "${cursor_pos:-0}" ]; do
printf '\n'
: $((i+=1))
i=$((i + 1))
done >&6
}