diff --git a/home/.config/shell/aliases b/home/.config/shell/aliases index ece4962..aa96ff9 100755 --- a/home/.config/shell/aliases +++ b/home/.config/shell/aliases @@ -81,7 +81,8 @@ alias zbi='z -b -I' # pick parent directory to cd into with fzf ## Make aliases for individual cpython/pypy versions py_versions="\n2\n3\n3.6\n3.7\n3.8\n3.9\n3.10" -echo "$py_versions" | while read version; do +# shellcheck disable=SC2139 +echo "$py_versions" | while read -r version; do for python in python pypy; do [ "$python" = "python" ] && prefix="py" || prefix="pypy" @@ -251,7 +252,7 @@ alias tty-clock='tty-clock -Ssc' # Terminal clock screensaver alias rick='curl -s -L https://raw.githubusercontent.com/ItsDrike/rickrollrc/master/roll.sh| bash' # Terminal rickroll # If user is not root, pass all commands via sudo/doas -if [ $UID -ne 0 ]; then +if [ "$(id -u)" -ne 0 ]; then # Enable aliases to be sudoed/doased # with doas having precedence over sudo if found @@ -266,7 +267,7 @@ fi # enable color support if [ -x /usr/bin/dircolors ]; then - test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + (test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)") || eval "$(dircolors -b)" alias dir='dir --color=auto' alias vdir='vdir --color=auto' @@ -284,7 +285,7 @@ fi # Normalize `open` across Linux, macOS, and Windows. # This is needed to make `open` function (see below) cross-platform -if [ ! $(uname -s) = 'Darwin' ]; then +if [ ! "$(uname -s)" = 'Darwin' ]; then if grep -q Microsoft /proc/version; then # Ubuntu on Windows using the Linux subsystem alias open='explorer.exe' @@ -295,10 +296,12 @@ fi # Functions if [ -f ~/.config/shell/functions ]; then - source ~/.config/shell/functions + # shellcheck source=/home/itsdrike/.config/shell/functions + . "$HOME/.config/shell/functions" fi # Extra if [ -f ~/.config/shell/extra ]; then - source ~/.config/shell/extra + # shellcheck source=/home/itsdrike/.config/shell/extra + . "$HOME/.config/shell/extra" fi diff --git a/home/.config/shell/environment b/home/.config/shell/environment index bdb0d73..7e05d43 100755 --- a/home/.config/shell/environment +++ b/home/.config/shell/environment @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # Environmental variable definitions. # This file is only sourced once after login, unlike .zshrc/.bashrc @@ -8,6 +8,8 @@ # which means the XDG definitions will be ignored anyway, and # defining them may break programs when root is actually logged in. +# Define some variables for POSIX compatibility +uid="$(id -u)" # Default programs export EDITOR="nvim" @@ -18,7 +20,7 @@ export TERMINAL="alacritty" export XDG_CONFIG_HOME="$HOME/.config" export XDG_CACHE_HOME="$HOME/.cache" export XDG_DATA_HOME="$HOME/.local/share" -export XDG_RUNTIME_DIR="/run/user/$UID" +export XDG_RUNTIME_DIR="/run/user/$uid" # Per-Application XDG settings export ZDOTDIR="$XDG_CONFIG_HOME/zsh" @@ -44,6 +46,7 @@ export NERDTREE_BOOKMARKS="$XDG_CONFIG_HOME/NERDTreeBookmarks" # Colorful man pages # If bat is installed, use it as manpager +# shellcheck disable=SC2155 if command -v bat > /dev/null; then export MANPAGER="sh -c 'col -bx | bat -l man -p'" else @@ -64,3 +67,6 @@ export XSECURELOCK_SHOW_DATETIME=1 # Show current date and time in xsecurelock export QT_QPA_PLATFORMTHEME=qt5ct # Have QT use the theme from qt5ct #export QT_QPA_PLATFORMTHEME="gtk2" # Have QT use gtk2 theme. +# Remove irrelevant variables added for posix compatibility +unset posix + diff --git a/home/.config/shell/functions b/home/.config/shell/functions index 34f14d7..81c8b26 100755 --- a/home/.config/shell/functions +++ b/home/.config/shell/functions @@ -1,18 +1,23 @@ -#!/usr/bin/env zsh +#!/bin/sh +# TODO: Currently, this file isn't entirely POSIX compatible, +# it will run fine with bash or zsh, however some functions may cause +# issues with pure POSIX. The fill will however run fine, the errors +# would only occur if the incompatible functions would be started. # Show application listening on given port -function port() { - sudo netstat -pln | grep $1 | awk '{print $NF}' +port() { + sudo netstat -pln | grep "$1" | awk '{print $NF}' } # Create a new directory and enter it -function mkd() { - mkdir -p "$@" && cd "$_"; +mkd() { + # shellcheck disable=SC2164 + mkdir -p "$1" && cd "$1"; } # `o` with no arguments opens the current directory, otherwise opens the given # location -function o() { +o() { if [ $# -eq 0 ]; then open .; else @@ -21,16 +26,16 @@ function o() { } # Use bat for nicer git diffs -function batdiff() { +batdiff() { git diff --name-only --diff-filter=d | xargs bat --diff } # Determine size of a file or total size of a directory -function dirsize() { +dirsize() { if du -b /dev/null > /dev/null 2>&1; then - local arg=-sbh; + arg=-sbh; else - local arg=-sh; + arg=-sh; fi if [[ -n "$*" ]]; then \du $arg -- "$@"; @@ -39,10 +44,10 @@ function dirsize() { fi; } -function randmac() { - sudo ip link set dev $1 down - sudo macchanger -A $1 - sudo ip link set dev $1 up +randmac() { + sudo ip link set dev "$1" down + sudo macchanger -A "$1" + sudo ip link set dev "$1" up } # Go to the root of a git tree @@ -59,76 +64,76 @@ cdgit () { } # Create a data URL from a file -function dataurl() { - local mimeType=$(file -b --mime-type "$1"); - if [[ $mimeType == text/* ]]; then - mimeType="${mimeType};charset=utf-8"; - fi - echo "data:${mimeType};base64,$(openssl base64 -in "$1" | tr -d '\n')"; +dataurl() { + mimeType="$(file -b --mime-type "$1")" + if echo "$mimeType" | grep -e "^text/.*$" >/dev/null; then + mimeType="${mimeType};charset=utf-8" + fi + echo "data:${mimeType};base64,$(openssl base64 -in "$1" | tr -d '\n')"; } # `tre` is a shorthand for `tree` with hidden files and color enabled, ignoring # the `.git` directory, listing directories first. The output gets piped into # `less` with options to preserve color and line numbers, unless the output is # small enough for one screen. -function tre() { - tree -I '.git|node_modules|bower_components' --group-directories-first "$@" | less -FRNX; +tre() { + tree -I '.git|node_modules|bower_components' --group-directories-first "$@" | less -FRNX; } # Show all the names (CNs and SANs) listed in the SSL certificate # for a given domain -function getcertnames() { - if [ -z "${1}" ]; then - echo "ERROR: No domain specified."; - return 1; - fi; +getcertnames() { + if [ -z "${1}" ]; then + echo "ERROR: No domain specified."; + return 1; + fi; - local domain="${1}"; - echo "Testing ${domain}…"; - echo ""; # newline + domain="${1}"; + echo "Testing ${domain}…"; + echo ""; # newline - local tmp=$(echo -e "GET / HTTP/1.0\nEOT" \ - | openssl s_client -connect "${domain}:443" -servername "${domain}" 2>&1); + tmp=$(echo -e "GET / HTTP/1.0\nEOT" \ + | openssl s_client -connect "${domain}:443" -servername "${domain}" 2>&1); - if [[ "${tmp}" = *"-----BEGIN CERTIFICATE-----"* ]]; then - local certText=$(echo "${tmp}" \ - | openssl x509 -text -certopt "no_aux, no_header, no_issuer, no_pubkey, \ - no_serial, no_sigdump, no_signame, no_validity, no_version"); - echo "Common Name:"; - echo ""; # newline - echo "${certText}" | grep "Subject:" | sed -e "s/^.*CN=//" | sed -e "s/\/emailAddress=.*//"; - echo ""; # newline - echo "Subject Alternative Name(s):"; - echo ""; # newline - echo "${certText}" | grep -A 1 "Subject Alternative Name:" \ - | sed -e "2s/DNS://g" -e "s/ //g" | tr "," "\n" | tail -n +2; - return 0; - else - echo "ERROR: Certificate not found."; - return 1; - fi; + if [[ "${tmp}" = *"-----BEGIN CERTIFICATE-----"* ]]; then + certText=$(echo "${tmp}" \ + | openssl x509 -text -certopt "no_aux, no_header, no_issuer, no_pubkey, \ + no_serial, no_sigdump, no_signame, no_validity, no_version"); + echo "Common Name:"; + echo ""; # newline + echo "${certText}" | grep "Subject:" | sed -e "s/^.*CN=//" | sed -e "s/\/emailAddress=.*//"; + echo ""; # newline + echo "Subject Alternative Name(s):"; + echo ""; # newline + echo "${certText}" | grep -A 1 "Subject Alternative Name:" \ + | sed -e "2s/DNS://g" -e "s/ //g" | tr "," "\n" | tail -n +2; + return 0; + else + echo "ERROR: Certificate not found."; + return 1; + fi; } # Compare original and gzipped file size -function gz-compare() { - local origsize=$(wc -c < "$1"); - local gzipsize=$(gzip -c "$1" | wc -c); - local ratio=$(echo "$gzipsize * 100 / $origsize" | bc -l); - printf "orig: %d bytes\n" "$origsize"; - printf "gzip: %d bytes (%2.2f%%)\n" "$gzipsize" "$ratio"; +gz_compare() { + origsize=$(wc -c < "$1"); + gzipsize=$(gzip -c "$1" | wc -c); + ratio=$(echo "$gzipsize * 100 / $origsize" | bc -l); + printf "orig: %d bytes\n" "$origsize"; + printf "gzip: %d bytes (%2.2f%%)\n" "$gzipsize" "$ratio"; } # Extract almost any archive -function extract { +extract() { if [ -z "$1" ]; then # display usage if no parameters given echo "Usage: extract ." echo " extract [path/file_name_2.ext] [path/file_name_3.ext]" return 1 else - for n in $@ + for n in "$@" do if [ -f "$n" ] ; then case "${n%,}" in @@ -158,17 +163,18 @@ fi } # Create a .tar.gz archive, using `zopfli`, `pigz` or `gzip` for compression -function targz() { +targz() { # Combine given names spearated with spaces as the filename - local tmpFile="${@%/}.tar"; - tar -cvf "${tmpFile}" "${@}" || return 1; + tmpFile="${*%/}.tar" + + tar -cvf "${tmpFile}" "${@}" || return 1 size=$( stat -f"%z" "${tmpFile}" 2> /dev/null; # macOS `stat` stat -c"%s" "${tmpFile}" 2> /dev/null; # GNU `stat` ); - local cmd=""; + cmd=""; if (( size < 52428800 )) && hash zopfli 2> /dev/null; then # the .tar file is smaller than 50 MB and Zopfli is available; use it cmd="zopfli"; @@ -192,11 +198,12 @@ function targz() { echo "${tmpFile}.gz ($((zippedSize / 1000)) kB) created successfully."; } -function anonymize { +anonymize() { # Reset the prompt on initial run to allow this script # to be ran multiple times without user having to reload # PS1 manually - source ${XDG_CONFIG_DIR:-$HOME/.config}/shell/prompt + # shellcheck source=/home/itsdrike/.config/shell/prompt + . "${XDG_CONFIG_DIR:-$HOME/.config}/shell/prompt" # Regular expression to match 0-255 numbers (color) color_int_re='^(0+)?([0-9]{1,2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])$' @@ -211,7 +218,7 @@ function anonymize { AT_COLOR="%F{004}" MACHINE_COLOR="%F{070}" - while [[ $# -gt 0 ]]; do + while [ $# -gt 0 ]; do key=$1 case $key in diff --git a/home/.config/shell/keybinds b/home/.config/shell/keybinds index 284df26..543988b 100755 --- a/home/.config/shell/keybinds +++ b/home/.config/shell/keybinds @@ -1,4 +1,5 @@ #!/usr/bin/env zsh +# shellcheck disable=SC2030,SC2031 # Set default keybindings (mostly from oh-my-zsh) # Make sure that the terminal is in application mode when zle is active, since @@ -18,30 +19,30 @@ fi bindkey -e # Start typing + [Up-Arrow] - fuzzy find history forward -if [[ -n "${terminfo[kcuu1]}" ]]; then +if [ -n "${terminfo[kcuu1]}" ]; then autoload -U up-line-or-beginning-search zle -N up-line-or-beginning-search bindkey "${terminfo[kcuu1]}" up-line-or-beginning-search fi # Start typing + [Down-Arrow] - fuzzy find history backward -if [[ -n "${terminfo[kcud1]}" ]]; then +if [ -n "${terminfo[kcud1]}" ]; then autoload -U down-line-or-beginning-search zle -N down-line-or-beginning-search bindkey "${terminfo[kcud1]}" down-line-or-beginning-search fi # [Home] - Go to beginning of line -[[ -n "${terminfo[khome]}" ]] && bindkey "${terminfo[khome]}" beginning-of-line || bindkey "^[[H" beginning-of-line +([ -n "${terminfo[khome]}" ] && bindkey "${terminfo[khome]}" beginning-of-line) || bindkey "^[[H" beginning-of-line # [End] - Go to end of line -[[ -n "${terminfo[kend]}" ]] && bindkey "${terminfo[kend]}" end-of-line || bindkey "^[[F" end-of-line +([ -n "${terminfo[kend]}" ] && bindkey "${terminfo[kend]}" end-of-line) || bindkey "^[[F" end-of-line # [Shift-Tab] - move through the completion menu backwards -[[ -n "${terminfo[kcbt]}" ]] && bindkey "${terminfo[kcbt]}" reverse-menu-complete +[ -n "${terminfo[kcbt]}" ] && bindkey "${terminfo[kcbt]}" reverse-menu-complete # [Backspace] - delete backward bindkey '^?' backward-delete-char # [Delete] - delete forward -[[ -n "${terminfo[kdch1]}" ]] && bindkey "${terminfo[kdch1]}" delete-char || bindkey "^[[3~" delete-char +([ -n "${terminfo[kdch1]}" ] && bindkey "${terminfo[kdch1]}" delete-char) || bindkey "^[[3~" delete-char # [Ctrl-Delete] - delete whole forward-word bindkey '^[[3;5~' kill-word @@ -53,9 +54,9 @@ bindkey '^[[1;5D' backward-word # [Ctrl-r] - Search backward incrementally for a specified string. The string may begin with ^ to anchor the search to the beginning of the line. bindkey '^r' history-incremental-search-backward # [PageUp] - Up a line of history -[[ -n "${terminfo[kpp]}" ]] && bindkey "${terminfo[kpp]}" up-line-or-history +[ -n "${terminfo[kpp]}" ] && bindkey "${terminfo[kpp]}" up-line-or-history # [PageDown] - Down a line of history -[[ -n "${terminfo[knp]}" ]] && bindkey "${terminfo[knp]}" down-line-or-history +[ -n "${terminfo[knp]}" ] && bindkey "${terminfo[knp]}" down-line-or-history # [Space] - do history expansion on space bindkey ' ' magic-space diff --git a/home/.config/shell/prompt b/home/.config/shell/prompt index 0fe1740..ca0aaa3 100755 --- a/home/.config/shell/prompt +++ b/home/.config/shell/prompt @@ -1,4 +1,5 @@ #!/usr/bin/env zsh +# shellcheck disable=SC2155 # Configuration variables: @@ -75,7 +76,7 @@ working_directory() { if [ $USE_SHORTENED_WORKDIR != 1 ]; then echo -n " $BLUE$~" - elif [ $TERM = "linux" ]; then + elif [ "$TERM" = "linux" ]; then echo -n " $BLUE%(5~|%-1~/.../%3~|%4~)" else echo -n " $BLUE%(5~|%-1~/…/%3~|%4~)" @@ -96,7 +97,7 @@ exec_time_preexec_hook() { exec_time_precmd_hook() { [[ $SHOW_CMD_TIME == 0 ]] && return [[ -z $PROMPT_EXEC_TIME_START ]] && return - local PROMPT_EXEC_TIME_STOP=$(date +%s.%N) + local PROMPT_EXEC_TIME_STOP="$(date +%s.%N)" PROMPT_EXEC_TIME_DURATION=$(echo "($PROMPT_EXEC_TIME_STOP - $PROMPT_EXEC_TIME_START) * 1000" | bc -l) unset PROMPT_EXEC_TIME_START } @@ -104,24 +105,24 @@ format_time() { # Do some formatting to get nice time (e.g. 2m 12s) from miliseconds # $1 is the milisecond amount (int or float) # $2 is the precision (ms/s/m/h/d) - local T=$1 - local D=$(echo "scale=0;$T/1000/60/60/24" | bc -l) - local H=$(echo "scale=0;$T/1000/60/60%24" | bc -l) - local M=$(echo "scale=0;$T/1000/60%60" | bc -l) - local S=$(echo "scale=0;$T/1000%60" | bc -l) - local MS=$(echo "scale=0;$T%1000" | bc -l) + local T="$1" + local D="$(echo "scale=0;$T/1000/60/60/24" | bc -l)" + local H="$(echo "scale=0;$T/1000/60/60%24" | bc -l)" + local M="$(echo "scale=0;$T/1000/60%60" | bc -l)" + local S="$(echo "scale=0;$T/1000%60" | bc -l)" + local MS="$(echo "scale=0;$T%1000" | bc -l)" local precision=$2 local out="" case "$precision" in - "ms") [[ $MS > 0 ]] && out="$(printf "%dms" $MS) ${out}"; precision="s" ;& - "s") [[ $S > 0 ]] && out="$(printf "%ds" $S) ${out}"; precision="m" ;& - "m") [[ $M > 0 ]] && out="$(printf "%dm" $M) ${out}"; precision="h" ;& - "h") [[ $H > 0 ]] && out="$(printf "%dh" $H) ${out}"; precision="d" ;& - "d") [[ $D > 0 ]] && out="$(printf "%dd" $D) ${out}" ;; + "ms") [[ "$MS" -gt 0 ]] && out="$(printf "%dms" "$MS") ${out}"; precision="s" ;& + "s") [[ "$S" -gt 0 ]] && out="$(printf "%ds" "$S") ${out}"; precision="m" ;& + "m") [[ "$M" -gt 0 ]] && out="$(printf "%dm" "$M") ${out}"; precision="h" ;& + "h") [[ "$H" -gt 0 ]] && out="$(printf "%dh" "$H") ${out}"; precision="d" ;& + "d") [[ "$D" -gt 0 ]] && out="$(printf "%dd" "$D") ${out}" ;; *) out="$T" ;; # Return $1 ($T) if precision wasn't specified/valid esac - printf "$out" + printf "%s" "$out" } display_cmd_time() { [[ $CMD_TIME_SHOW == 0 ]] && return @@ -134,7 +135,7 @@ display_cmd_time() { # this happens when all fields (seconds/minutes/...) are 0, # if we use milisecond precision, this will likely never happen # but with other precisions, it could - [[ "$(expr length "$time_took")" == 0 ]] && return + [ ${#time_took} -eq 0 ] && return echo -n " ${LBLUE}took ${time_took}" } @@ -158,7 +159,7 @@ PS2="$RED\ $RESET" # Right side prompt RPS1="" -if [ $TERM = "linux" ]; then +if [ "$TERM" = "linux" ]; then # Displaying cmd time here works, but often causes issues when we # resize the terminal, since right prompts can be annoying to deal # with when resizing. This would run relatively often so it makes