71 Commits

Author SHA1 Message Date
Dylan Araps
3ca67a75c4 pfetch: windows support 2019-10-01 10:34:48 +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 465 additions and 196 deletions

View File

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

View File

@@ -21,24 +21,53 @@ _/\ __)/_) pkgs 130
## OS support ## OS support
- [x] Linux (A myriad of distributions) - **Haiku**
- [x] MacOS - **MacOS**
- [x] OpenBSD - **Minix**
- [x] FreeBSD - **Solaris**
- [x] NetBSD - **BSD**
- [x] Haiku - DragonflyBSD
- FreeBSD
- NetBSD
- OpenBSD
- **Windows**
- Windows subsystem for Linux.
- **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
- Void Linux
- Other distributions are supported with a generic penguin logo.
## TODO ## TODO
- [ ] Add optional and additional information detection. - [ ] Add optional and additional information detection.
- [ ] CPU - [ ] Terminal Emulator ([#12](https://github.com/dylanaraps/pfetch/pull/12))
- [ ] Terminal Emulator
- The way I implement this in `neofetch` is interesting. - The way I implement this in `neofetch` is interesting.
- [ ] Terminal colors
- [ ] ???
- [ ] Expand operating system support. - [ ] Expand operating system support.
- [ ] Solaris ([#5](https://github.com/dylanaraps/pfetch/issues/5)) - [ ] Android
- [ ] MINIX ([#6](https://github.com/dylanaraps/pfetch/issues/6)) - [ ] iOS
- [ ] AIX ([#7](https://github.com/dylanaraps/pfetch/issues/7)) - [ ] AIX ([#7](https://github.com/dylanaraps/pfetch/issues/7))
- [ ] IRIX ([#8](https://github.com/dylanaraps/pfetch/issues/8)) - [ ] IRIX ([#8](https://github.com/dylanaraps/pfetch/issues/8))
- [ ] FreeMiNT ([#9](https://github.com/dylanaraps/pfetch/issues/9)) - [ ] FreeMiNT ([#9](https://github.com/dylanaraps/pfetch/issues/9))
@@ -46,7 +75,6 @@ _/\ __)/_) pkgs 130
- [ ] CYGWIN - [ ] CYGWIN
- [ ] MSYS - [ ] MSYS
- [ ] MINGW - [ ] MINGW
- [ ] WSL (*this is fairly simple*)
## Configuration ## Configuration
@@ -58,14 +86,14 @@ _/\ __)/_) pkgs 130
# Default: first example below # Default: first example below
# Valid: space separated string # Valid: space separated string
# #
# OFF by default: shell # OFF by default: shell editor wm de palette
PF_INFO="ascii title distro host kernel uptime pkgs memory" PF_INFO="ascii title os host kernel uptime pkgs memory"
# Example: Only ASCII. # Example: Only ASCII.
PF_INFO="ascii" PF_INFO="ascii"
# Example: Only Information. # 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. # Separator between info name and info data.
# Default: unset # Default: unset
@@ -96,6 +124,26 @@ PF_ALIGN=""
# Default: unset (auto) # Default: unset (auto)
# Valid: string # Valid: string
PF_ASCII="openbsd" 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 ## Credit

577
pfetch
View File

@@ -64,7 +64,7 @@ log() {
# Use 'set --' as a means of stripping all leading and trailing # Use 'set --' as a means of stripping all leading and trailing
# white-space from the info string. This also normalizes all # 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 # Disable the shellcheck warning for word-splitting
# as it's safe and intended ('set -f' disables globbing). # as it's safe and intended ('set -f' disables globbing).
@@ -95,13 +95,13 @@ log() {
printf '[3%sm%s\n' "${PF_COL2-7}" "$info" printf '[3%sm%s\n' "${PF_COL2-7}" "$info"
# Keep track of the number of times 'log()' has been run. # Keep track of the number of times 'log()' has been run.
: $((info_height+=1)) info_height=$((${info_height:-0} + 1))
} }
get_title() { get_title() {
# Username is retrieved by first checking '$USER' with a fallback # Username is retrieved by first checking '$USER' with a fallback
# to the 'whoami' command. # to the 'id -un' command.
user=${USER:-$(whoami)} user=${USER:-$(id -un)}
# Hostname is retrieved by first checking '$HOSTNAME' with a fallback # Hostname is retrieved by first checking '$HOSTNAME' with a fallback
# to the 'hostname' command. # to the 'hostname' command.
@@ -155,16 +155,44 @@ get_os() {
distro=$(lsb_release -sd) distro=$(lsb_release -sd)
else else
# Disable warning about shellcheck not being able # This used to be a simple '. /etc/os-release' but I believe
# to read '/etc/os-release'. This is fine. # this is insecure as we blindly executed whatever was in the
# shellcheck source=/dev/null # file. This parser instead simply handles 'key=val', treating
. /etc/os-release && distro=$PRETTY_NAME # 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 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 # Special cases for (independent) distributions which
# don't follow any os-release/lsb standards whatsoever. # don't follow any os-release/lsb standards whatsoever.
command -v crux && distro=$(crux) command -v crux && distro=$(crux)
command -v guix && distro='Guix System' 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*) Darwin*)
@@ -215,8 +243,35 @@ get_os() {
Haiku) Haiku)
# Haiku uses 'uname -v' for version information # Haiku uses 'uname -v' for version information
# instead of 'uname -r'. # instead of 'uname -r' which only prints '1'.
distro="Haiku $(uname -v)" 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
;;
CYGWIN*|MSYS*|MINGW*)
# Grab everything after the first instance of
# white-space in the command output of 'wmic'.
#
# The format of 'wmic' is as follows:
# Caption=Microsoft Windows 7 Enterprise
#
# This extracts: ^^^^^^^^^^^^^^^^^^^^
read -r _ distro <<-EOF
$(wmic os get Caption /value)
EOF
;; ;;
*) *)
@@ -231,7 +286,7 @@ get_kernel() {
case $os in case $os in
# Don't print kernel output on some systems as the # Don't print kernel output on some systems as the
# OS name includes it. # OS name includes it.
*BSD*|Haiku) ;; *BSD*|Haiku|Minix) ;;
*) *)
# '$kernel' is the cached output of 'uname -r'. # '$kernel' is the cached output of 'uname -r'.
@@ -253,7 +308,7 @@ get_host() {
host="$name $version $model" host="$name $version $model"
;; ;;
Darwin*|FreeBSD*) Darwin*|FreeBSD*|DragonFly*)
host=$(sysctl -n hw.model) host=$(sysctl -n hw.model)
;; ;;
@@ -265,6 +320,21 @@ get_host() {
*BSD*) *BSD*)
host=$(sysctl -n hw.vendor hw.product) host=$(sysctl -n hw.vendor hw.product)
;; ;;
CYGWIN*|MSYS*|MINGW*)
# Grab everything after the first instance of '=' in each
# line of the command output of 'wmic'. Append the output
# of each line to the '$host' variable.
#
# The format of 'wmic' is as follows:
# Manufacturer=VMware, Inc.
# Model=VMware Virtual Platform
while IFS='=' read -r _ val; do
host="${host}${val:+ $val}"
done <<-EOF
$(wmic computersystem get manufacturer,model /value)
EOF
;;
esac esac
# Turn the host string into an argument list so we can iterate # Turn the host string into an argument list so we can iterate
@@ -314,11 +384,11 @@ get_uptime() {
# converting that data into days, hours and minutes using simple # converting that data into days, hours and minutes using simple
# math. # math.
case $os in case $os in
Linux*) Linux*|Minix*|CYGWIN*|MSYS*|MINGW*)
IFS=. read -r s _ < /proc/uptime IFS=. read -r s _ < /proc/uptime
;; ;;
Darwin*|*BSD*) Darwin*|*BSD*|DragonFly*)
s=$(sysctl -n kern.boottime) s=$(sysctl -n kern.boottime)
# Extract the uptime in seconds from the following output: # Extract the uptime in seconds from the following output:
@@ -336,6 +406,19 @@ get_uptime() {
# regular seconds. # regular seconds.
s=$(($(system_time) / 1000000)) 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 esac
# Convert the uptime from seconds into days, hours and minutes. # Convert the uptime from seconds into days, hours and minutes.
@@ -352,6 +435,10 @@ get_uptime() {
} }
get_pkgs() { 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 # This works by first checking for which package managers are
# installed and finally by printing each package manager's # installed and finally by printing each package manager's
# package list with each package one per line. # package list with each package one per line.
@@ -372,27 +459,22 @@ get_pkgs() {
case $os in case $os in
Linux*) Linux*)
# Commands which print packages one per line. # Commands which print packages one per line.
command -v kiss && kiss l has bonsai && bonsai list
command -v bonsai && bonsai list has pacman-key && pacman -Qq
command -v pacman-key && pacman -Qq has dpkg && dpkg-query -f '.\n' -W
command -v dpkg && dpkg-query -f '.\n' -W has rpm && rpm -qa
command -v rpm && rpm -qa has xbps-query && xbps-query -l
command -v xbps-query && xbps-query -l has apk && apk info
command -v apk && apk info has guix && guix package --list-installed
# Directories containing packages. # Directories containing packages.
command -v brew && printf '%s\n' "$(brew --cellar)/"* has kiss && printf '%s\n' /var/db/kiss/installed/*/
command -v emerge && printf '%s\n' /var/db/pkg/*/*/ has brew && printf '%s\n' "$(brew --cellar)/"*
command -v pkgtool && printf '%s\n' /var/log/packages/* has emerge && printf '%s\n' /var/db/pkg/*/*/
has pkgtool && printf '%s\n' /var/log/packages/*
# GUIX requires two commands. # 'nix' requires two commands.
command -v guix && { has nix-store && {
guix package -p /run/current-system/profile -I
guix package -I
}
# NIX requires two commands.
command -v nix-store && {
nix-store -q --requisites /run/current-system/sw nix-store -q --requisites /run/current-system/sw
nix-store -q --requisites ~.nix-profile nix-store -q --requisites ~.nix-profile
} }
@@ -400,14 +482,14 @@ get_pkgs() {
Darwin*) Darwin*)
# Commands which print packages one per line. # Commands which print packages one per line.
command -v pkgin && pkgin list has pkgin && pkgin list
command -v port && port installed has port && port installed
# Directories containing packages. # Directories containing packages.
command -v brew && printf '%s\n' /usr/local/Cellar/* has brew && printf '%s\n' /usr/local/Cellar/*
;; ;;
FreeBSD*) FreeBSD*|DragonFly*)
pkg info pkg info
;; ;;
@@ -422,6 +504,23 @@ get_pkgs() {
Haiku) Haiku)
printf '%s\n' /boot/system/package-links/* 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
;;
CYGWIN*)
cygcheck -cd
;;
MSYS*)
pacman -Qq
;;
esac | wc -l esac | wc -l
` `
@@ -430,14 +529,14 @@ get_pkgs() {
get_memory() { get_memory() {
case $os in 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 # MemUsed = MemTotal + Shmem - MemFree - Buffers - Cached - SReclaimable
# Source: https://github.com/KittyKatt/screenFetch/issues/386 # Source: https://github.com/KittyKatt/screenFetch/issues/386
Linux*) Linux*|CYGWIN*|MSYS*|MINGW*)
# Parse the '/proc/meminfo' file splitting on ':' and 'k'. # Parse the '/proc/meminfo' file splitting on ':' and 'k'.
# The format of the file is 'key: 000kB' and an additional # The format of the file is 'key: 000kB' and an additional
# split is used on 'k' to filter out 'kB'. # 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 case $key in
MemTotal) MemTotal)
mem_used=$((mem_used + val)) mem_used=$((mem_used + val))
@@ -458,7 +557,7 @@ get_memory() {
mem_full=$((mem_full / 1024)) 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 # (wired + active + occupied) * 4 / 1024
Darwin*) Darwin*)
mem_full=$(($(sysctl -n hw.memsize) / 1024 / 1024)) mem_full=$(($(sysctl -n hw.memsize) / 1024 / 1024))
@@ -508,9 +607,9 @@ get_memory() {
EOF EOF
;; ;;
# Used memory is calculated using the following "formula" (FreeBSD): # Used memory is calculated using the following "formula":
# (inactive_count + free_count + cache_count) * page_size / 1024 # mem_full - ((inactive + free + cache) * page_size / 1024)
FreeBSD*) FreeBSD*|DragonFly*)
mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024)) mem_full=$(($(sysctl -n hw.physmem) / 1024 / 1024))
# Use 'set --' to store the output of the command in the # Use 'set --' to store the output of the command in the
@@ -532,7 +631,7 @@ get_memory() {
# $2: vm.stats.vm.v_inactive_count # $2: vm.stats.vm.v_inactive_count
# $3: vm.stats.vm.v_free_count # $3: vm.stats.vm.v_free_count
# $4: vm.stats.vm.v_cache_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*) NetBSD*)
@@ -540,7 +639,7 @@ get_memory() {
# NetBSD implements a lot of the Linux '/proc' filesystem, # NetBSD implements a lot of the Linux '/proc' filesystem,
# this uses the same parser as the Linux memory detection. # 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 case $key in
MemFree) MemFree)
mem_free=$((val / 1024)) mem_free=$((val / 1024))
@@ -567,135 +666,173 @@ get_memory() {
mem_used=$((mem_used / 1024 / 1024)) mem_used=$((mem_used / 1024 / 1024))
mem_full=$((mem_full / 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 esac
log memory "${mem_used:-?}M / ${mem_full:-?}M" >&6 log memory "${mem_used:-?}M / ${mem_full:-?}M" >&6
} }
get_term() { get_wm() {
# Workaround for macOS systems that don't support the case $os in
# "algorithm" of obtaining the terminal program name. # Don't display window manager on macOS.
# Darwin*) ;;
# This also doubles as a means of allowing the user to
# set whatever value they like here through the *)
# '$TERM_PROGRAM' environment variable. # xprop can be used to grab the window manager's properties
case $TERM_PROGRAM in # which contains the window manager's name under '_NET_WM_NAME'.
iTerm.app) term=iTerm2 ;; #
Terminal.app) term='Apple Terminal' ;; # The upside to using 'xprop' is that you don't need to hardcode
Hyper) term=HyperTerm ;; # a list of known window manager names. The downside is that
*) term=${TERM_PROGRAM%%.app} ;; # 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)
wm=${wm##*_NET_WM_NAME = \"}
wm=${wm%%\"*}
}
;;
esac esac
# Special case for TosWin2 (FreeMiNT) which doesn't log wm "$wm" >&6
# support the "algorithm" of obtaining the terminal }
# program name.
[ "$TERM" = tw52 ] || [ "$TERM" = tw100 ] &&
term=TosWin2
# Special case for when 'pfetch' is run over SSH.
[ "$SSH_CONNECTION" ] &&
term=$SSH_TTY
# This surprisingly reliable method of detecting the current get_de() {
# terminal emulator is kinda neat. # 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).
# #
# It works by looping through each parent of each process # Display the value of '$XDG_CURRENT_DESKTOP', if it's empty,
# starting with '$PPID' (the parent process ID) until we # display the value of '$DESKTOP_SESSION'.
# find a match or hit PID 1 (init). log de "${XDG_CURRENT_DESKTOP:-$DESKTOP_SESSION}" >&6
#
# On each iteration the name of the current parent process
# is checked against a list of good values and bad values.
# If no match is found we check the parent of the parent
# and so on.
#
# Using this method *no* terminal emulator names are
# hardcoded and the list remains small and general. In short
# it's basically a list of what *isn't* a terminal emulator
# and a list of places we should *stop*.
while [ -z "$term" ]; do
# This block is OS-specific and handles the fetching of
# the parent process (of the parent) and the fetching of
# said process' name.
case $os in
Linux*)
# On Linux some implementation of 'ps' aren't POSIX
# compliant, thankfully Linux provides this information
# though the '/proc' filesystem.
#
# This loops line by line over the '/proc/PID/status'
# file splitting at ':' and '<TAB>', we then look for
# the key containing 'PPid' and grab the value.
while IFS=': ' read -r key val; do
case $key in
PPid)
ppid=$val
break
;;
esac
done < "/proc/${ppid:-$PPID}/status"
# Get the name of the parent process.
read -r name < "/proc/$ppid/comm"
;;
Windows*)
# I need some assistance to add Windows support
# as the 'ps' command used in MINGW, MSYS and CYGWIN
# isn't POSIX compliant(?).
return
;;
*)
# POSIX compliant 'ps' makes this really easy,
# just two simple commands to grab the parent
# process ID and the ID's name.
ppid=$(ps -p "${ppid:-$PPID}" -o ppid=)
name=$(ps -p "$ppid" -o comm=)
;;
esac
# Check the parent process name against a list of good and bad
# values. On a bad value we either keep iterating up the parent
# process list or we stop altogether (PID 1 for example).
case $name in
# If the parent process name matches the user's shell (or
# anything that looks like a shell), do another iteration.
#
# This also includes 'screen' and anything that looks like
# 'su' or 'sudo'.
${SHELL##*/} | *sh | screen | su* ) ;;
# If the parent process name matches 'login', 'init' or
# '*Login*' we're most likely in the TTY and not a graphical
# session. In this case 'term' is set to the current TTY and
# we end here.
login* | *Login* | init)
term=$(tty)
;;
# If the parent process name matches anything in this list
# we can no longer continue. We've either hit PID 1 or a parent
# which *won't* lead to the terminal emulator's PID.
ruby | systemd | python* | 1 | sshd* | tmux* |\
USER*PID* | kdeinit* | launchd* | '' )
break
;;
# If none of the above have matched we've reached the terminal
# emulator's PID and we can end here.
*)
term=${name##*/}
;;
esac
done
[ "$term" ] && log term "$term" >&6
} }
get_shell() { get_shell() {
# Display the basename of the '$SHELL' environment variable.
log shell "${SHELL##*/}" >&6 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() { get_ascii() {
# This is a simple function to read the contents of # This is a simple function to read the contents of
# an ascii file from 'stdin'. It allows for the use # an ascii file from 'stdin'. It allows for the use
@@ -744,6 +881,17 @@ get_ascii() {
EOF EOF
;; ;;
[Aa]ndroid*)
read_ascii 2 <<-EOF
${c2} ;, ,;
';,.-----.,;'
,' ',
/ O O \\
| |
'-----------------'
EOF
;;
[Aa]rch*) [Aa]rch*)
read_ascii 4 <<-EOF read_ascii 4 <<-EOF
${c6} /\\ ${c6} /\\
@@ -803,6 +951,18 @@ get_ascii() {
EOF EOF
;; ;;
[Dd]ragon[Ff]ly*)
read_ascii 1 <<-EOF
,${c1}_${c7},
('-_${c1}|${c7}_-')
>--${c1}|${c7}--<
(_-'${c1}|${c7}'-_)
${c1}|
|
|
EOF
;;
[Ee]lementary*) [Ee]lementary*)
read_ascii <<-EOF read_ascii <<-EOF
${c7} _______ ${c7} _______
@@ -961,6 +1121,19 @@ get_ascii() {
EOF 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]*) [Mm][Xx]*)
read_ascii <<-EOF read_ascii <<-EOF
${c7} \\\\ / ${c7} \\\\ /
@@ -1068,6 +1241,27 @@ get_ascii() {
EOF EOF
;; ;;
[Ss]un[Oo][Ss])
read_ascii 3 <<-EOF
${c3} . .; .
. :; :: ;: .
.;. .. .. .;.
.. .. .. ..
.;, ,;.
EOF
;;
[Uu]buntu*)
read_ascii 3 <<-EOF
${c3} _
---(_)
_/ --- \\
(_) | |
\\ --- _/
---(_)
EOF
;;
[Vv]oid*) [Vv]oid*)
read_ascii 2 <<-EOF read_ascii 2 <<-EOF
${c2} _______ ${c2} _______
@@ -1104,8 +1298,12 @@ get_ascii() {
# information. The 'sed' is used to strip 'm' color codes from # information. The 'sed' is used to strip 'm' color codes from
# the ascii art so they don't affect the width variable. # the ascii art so they don't affect the width variable.
while read -r line; do while read -r line; do
: $((ascii_height+=1)) ascii_height=$((${ascii_height:-0} + 1))
ascii_width=$((${#line} > ascii_width ? ${#line} : ascii_width))
# 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 # Using '<<-EOF' is the only way to loop over a command's
# output without the use of a pipe ('|'). # output without the use of a pipe ('|').
@@ -1116,24 +1314,17 @@ get_ascii() {
EOF EOF
# Add a gap between the ascii art and the information. # 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 # Print the ascii art and position the cursor back where we
# started prior to printing it. # started prior to printing it.
# '[?7l': Disable line-wrapping.
# '[?25l': Hide the cursor.
# '[1m': Print the ascii in bold. # '[1m': Print the ascii in bold.
# '[m': Clear bold. # '[m': Clear bold.
# '[%sA': Move the cursor up '$ascii_height' amount of lines. # '[%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() { 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 # Hide 'stderr' unless the first argument is '-v'. This saves
# polluting the script with '2>/dev/null'. # polluting the script with '2>/dev/null'.
[ "$1" = -v ] || exec 2>/dev/null [ "$1" = -v ] || exec 2>/dev/null
@@ -1152,6 +1343,26 @@ main() {
c7=''; c8='' 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 # Store the output of 'uname' to avoid calling it multiple times
# throughout the script. 'read <<EOF' is the simplest way of reading # throughout the script. 'read <<EOF' is the simplest way of reading
# a command into a list of variables. # a command into a list of variables.
@@ -1170,18 +1381,22 @@ main() {
# Disable globbing and set the positional parameters to the # Disable globbing and set the positional parameters to the
# contents of 'PF_INFO'. # contents of 'PF_INFO'.
set -f set -f
set +f ${PF_INFO-ascii title os host kernel term uptime pkgs memory} set +f ${PF_INFO-ascii title os host kernel uptime pkgs memory}
# Iterate over the info functions to determine the lengths of the # Iterate over the info functions to determine the lengths of the
# "info names" for output alignment. The option names and subtitles # "info names" for output alignment. The option names and subtitles
# match 1:1 so this is thankfully simple. # match 1:1 so this is thankfully simple.
for info; do for info; do
command -v "get_$info" >/dev/null && command -v "get_$info" >/dev/null || continue
info_length=$((${#info} > info_length ? ${#info} : info_length))
# This was a ternary operation but they aren't supported in
# Minix's shell.
[ "${#info}" -gt "${info_length:-0}" ] &&
info_length=${#info}
done done
# Add an additional space of length to act as a gap. # 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. # Iterate over the above list and run any existing "get_" functions.
for info; do "get_$info"; done for info; do "get_$info"; done
@@ -1189,15 +1404,19 @@ main() {
# Position the cursor below both the ascii art and information lines # Position the cursor below both the ascii art and information lines
# according to the height of both. If the information exceeds the ascii # 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. # art in height, don't touch the cursor (0/unset), else move it down
cursor_pos=$((info_height > ascii_height ? 0 : ascii_height - info_height)) # N lines.
#
# This was a ternary operation but they aren't supported in Minix's shell.
[ "$info_height" -lt "$ascii_height" ] &&
cursor_pos=$((ascii_height - info_height))
# Print '$cursor_pos' amount of newlines to correctly position the # Print '$cursor_pos' amount of newlines to correctly position the
# cursor. This used to be a 'printf $(seq X X)' however 'seq' is only # cursor. This used to be a 'printf $(seq X X)' however 'seq' is only
# typically available (by default) on GNU based systems! # 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' printf '\n'
: $((i+=1)) i=$((i + 1))
done >&6 done >&6
} }