From d13a21a734b23236f03f67bc1951aba9975ce361 Mon Sep 17 00:00:00 2001 From: Ben Grande Date: Tue, 6 Aug 2024 17:27:08 +0200 Subject: [PATCH] fix: avoid echo usage Echo can interpret operand as an option and checking every variable to be echoed is troublesome while with printf, if the format specifier is present before the operand, printing as string can be enforced. --- files/dom0/.local/bin/dom0/qvm-restart | 3 ++- files/dom0/.local/bin/dom0/qvm-stats | 4 ++-- .../share/bash-completion/completions/qvm | 6 ++--- files/git/.config/git/config | 8 +++---- files/git/.config/git/shell/.git-shell-lib | 10 ++++---- .../git/shell/.no-interactive-login.sample | 2 +- files/git/.config/git/shell/description | 6 ++--- files/git/.config/git/shell/init | 2 +- files/git/.config/git/shell/list | 4 ++-- .../git/template/hooks/pre-receive.sample | 23 +++++++++++-------- .../git/template/hooks/prepare-commit-msg | 4 ++-- files/git/.local/bin/git-server-setup | 2 +- files/mutt/.local/bin/mutt-sorcerer | 6 ++--- files/qvm-copy-dotfiles | 9 ++++---- files/sh/.config/bash/bashrc | 2 +- files/sh/.config/sh/profile | 2 +- files/sh/.config/sh/shrc | 2 +- files/sh/.local/bin/has | 2 +- files/sh/.local/bin/resize-terminal | 8 ++++--- files/tmux/.local/bin/tmux-sorcerer | 2 +- 20 files changed, 57 insertions(+), 50 deletions(-) diff --git a/files/dom0/.local/bin/dom0/qvm-restart b/files/dom0/.local/bin/dom0/qvm-restart index 9f503d5..35cb44b 100755 --- a/files/dom0/.local/bin/dom0/qvm-restart +++ b/files/dom0/.local/bin/dom0/qvm-restart @@ -6,7 +6,8 @@ set -eu -test -n "${1:-}" || { echo "Usage: ${0##*/} QUBE [QUBE ...]"; exit 1; } +test -n "${1:-}" || + { printf '%s\n' "Usage: ${0##*/} QUBE [QUBE ...]"; exit 1; } vms="${*}" diff --git a/files/dom0/.local/bin/dom0/qvm-stats b/files/dom0/.local/bin/dom0/qvm-stats index 5c92b2e..235b32e 100755 --- a/files/dom0/.local/bin/dom0/qvm-stats +++ b/files/dom0/.local/bin/dom0/qvm-stats @@ -10,11 +10,11 @@ set -eu if ! command -v sensors >/dev/null; then - echo "Program not installed: sensors" >&2 + printf '%s\n' "Program not installed: sensors" >&2 exit 1 fi if ! command -v xentop >/dev/null; then - echo "Program not installed: xentop" >&2 + printf '%s\n' "Program not installed: xentop" >&2 exit 1 fi diff --git a/files/dom0/.local/share/bash-completion/completions/qvm b/files/dom0/.local/share/bash-completion/completions/qvm index 9075fc6..89784c8 100644 --- a/files/dom0/.local/share/bash-completion/completions/qvm +++ b/files/dom0/.local/share/bash-completion/completions/qvm @@ -24,7 +24,7 @@ _get-cword-pos() { [[ ${COMP_WORDS[i]} == -* ]] && continue ((index++)) done - echo ${index} + printf '%s\n' "${index}" } # Get the relative position of the first COMP_CWORD with option words ignored @@ -33,10 +33,10 @@ _get-first-cword() { local i for ((i=1; i<=COMP_CWORD; i++)); do [[ ${COMP_WORDS[i]} == -* ]] && continue - echo "${COMP_WORDS[i]}" + printf '%s\n' "${COMP_WORDS[i]}" return 0 done - echo "" + printf '%s\n' "" } diff --git a/files/git/.config/git/config b/files/git/.config/git/config index d9421d9..a9d88f2 100644 --- a/files/git/.config/git/config +++ b/files/git/.config/git/config @@ -71,16 +71,16 @@ add-unmerged = "!f() { git diff --name-status --diff-filter=U | cut -f2 ; }; git add $(f)" ; List tips of branches that are not in the first arg. ; git tips origin/master ^origin/alternate | git oneline - oneline ="!_() { $(test $# -eq 0 && echo xargs -L1) git log --no-walk --decorate --oneline \"$@\"; }; _" - tips = "!_() { t=$(git rev-list --no-merges --max-count=1 \"$@\"); if test -n \"$t\"; then echo $t; _ \"$@\" ^$t; fi; }; _" + oneline ="!_() { $(test $# -eq 0 && printf '%s\n' \"xargs -L1\") git log --no-walk --decorate --oneline \"$@\"; }; _" + tips = "!_() { t=$(git rev-list --no-merges --max-count=1 \"$@\"); if test -n \"$t\"; then printf '%s\n' \"$t\"; _ \"$@\" ^$t; fi; }; _" ; Submodules. sub-update = !sh -c 'git checkout $1 && git submodule update --recursive' ; Signed tags and commits stag = "!sh -c 'commit_id=\"$(git rev-parse --verify \"$@\")\"; \ - tag_name=\"signed_tag_for_$(echo $commit_id | cut -c 1-8)\"; \ + tag_name=\"signed_tag_for_$(printf '%s\n' \"$commit_id\" | cut -c 1-8)\"; \ git tag -s \"$tag_name\" \ -m \"Tag for commit $commit_id\" \"$commit_id\"; \ - echo \"$tag_name\"'" - + printf '%s\n' \"$tag_name\"'" - ptag = !git push $(git config branch.$(git branch --show-current).remote) $(git describe) vtag = !git verify-tag -v $(git describe) vhci = !git verify-commit -v $(git rev-parse HEAD) diff --git a/files/git/.config/git/shell/.git-shell-lib b/files/git/.config/git/shell/.git-shell-lib index e85a7d6..8559961 100755 --- a/files/git/.config/git/shell/.git-shell-lib +++ b/files/git/.config/git/shell/.git-shell-lib @@ -18,14 +18,14 @@ regex="^[A-Za-z0-9]+([A-Za-z0-9_.-]+[A-Za-z0-9]+)?$" description_regex="^[A-Za-z0-9 _.-]+$" fail_invalid_name(){ - echo "Error: invalid value for key: $1" >&2 + printf '%s\n' "Error: invalid value for key: $1" >&2 exit 1 } test_description(){ key="$1" value="$2" - if ! (echo "${value}" | grep -E -q -e "${description_regex}"); then + if ! (printf '%s\n' "${value}" | grep -E -q -e "${description_regex}"); then fail_invalid_name "${key}" fi } @@ -33,7 +33,7 @@ test_description(){ test_name(){ key="$1" value="$2" - if ! (echo "${value}" | grep -E -q -e "${regex}"); then + if ! (printf '%s\n' "${value}" | grep -E -q -e "${regex}"); then fail_invalid_name "${key}" fi } @@ -48,12 +48,12 @@ clean_repo_name(){ is_bare(){ _repo="$1" if ! test -d "${_repo}"; then - echo "Repository doesn't exist: ${_repo}" >&2 + printf '%s\n' "Repository doesn't exist: ${_repo}" >&2 return 1 fi bare_repo_check="$(git -C "${_repo}" rev-parse --is-bare-repository)" if ! test "${bare_repo_check}" = "true"; then - echo "Repository is not bare: ${_repo}" >&2 + printf '%s\n' "Repository is not bare: ${_repo}" >&2 return 1 fi } diff --git a/files/git/.config/git/shell/.no-interactive-login.sample b/files/git/.config/git/shell/.no-interactive-login.sample index 098fdd3..68af680 100755 --- a/files/git/.config/git/shell/.no-interactive-login.sample +++ b/files/git/.config/git/shell/.no-interactive-login.sample @@ -6,7 +6,7 @@ set -eu -echo "Hello there. You've successfully authenticated, but interactive +printf '%s\n' "Hello there. You've successfully authenticated, but interactive shell access is not available. You have access to these repositories:" >&2 "${0%/*}"/list >&2 diff --git a/files/git/.config/git/shell/description b/files/git/.config/git/shell/description index eb9c2bd..7fe02ec 100755 --- a/files/git/.config/git/shell/description +++ b/files/git/.config/git/shell/description @@ -11,7 +11,7 @@ set -eu usage(){ # shellcheck disable=2154 - echo "usage: ${0##*/} SECTION REPOSITORY [DESCRIPTION] + printf '%s\n' "usage: ${0##*/} SECTION REPOSITORY [DESCRIPTION] note: prints the current description if none description is specified.:w regex: ${regex}" >&2 exit 1 @@ -35,7 +35,7 @@ if test -z "${3-}"; then exit 0 fi -description="$(echo "$3" | cut -c 1-80)" +description="$(printf '%s\n' "$3" | cut -c 1-80)" test_description description "${description}" -echo "${description}" | tee "${description_file}" +printf '%s\n' "${description}" | tee "${description_file}" diff --git a/files/git/.config/git/shell/init b/files/git/.config/git/shell/init index 1abd22d..da51369 100755 --- a/files/git/.config/git/shell/init +++ b/files/git/.config/git/shell/init @@ -11,7 +11,7 @@ set -eu usage(){ # shellcheck disable=2154 - echo "usage: ${0##*/} SECTION REPOSITORY [BRANCH] + printf '%s\n' "usage: ${0##*/} SECTION REPOSITORY [BRANCH] regex: ${regex}" >&2 exit 1 } diff --git a/files/git/.config/git/shell/list b/files/git/.config/git/shell/list index 79f2653..42ef18c 100755 --- a/files/git/.config/git/shell/list +++ b/files/git/.config/git/shell/list @@ -14,7 +14,7 @@ set -eu usage(){ # shellcheck disable=2154 - echo "usage: ${0##*/} [SECTION] + printf '%s\n' "usage: ${0##*/} [SECTION] regex: ${regex}" >&2 exit 1 } @@ -28,7 +28,7 @@ esac # shellcheck disable=SC2154 if ! test -d "${base}/${section}"; then - echo "Section doesn't exist: ${section}" >&2 + printf '%s\n' "Section doesn't exist: ${section}" >&2 exit 1 fi diff --git a/files/git/.config/git/template/hooks/pre-receive.sample b/files/git/.config/git/template/hooks/pre-receive.sample index 7d4cf8a..2680e8b 100755 --- a/files/git/.config/git/template/hooks/pre-receive.sample +++ b/files/git/.config/git/template/hooks/pre-receive.sample @@ -41,7 +41,7 @@ tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/XXXXXX")" trap 'rm -f "${tmpdir}"' HUP INT QUIT ABRT TERM EXIT err(){ - echo "${*}" >&2 + printf '%s\n' "${*}" >&2 } require_signed_push(){ @@ -78,7 +78,7 @@ check_signed_push(){ check_signed_push_keyring(){ true "Using keyring to verify push certificate: ${GIT_PUSH_CERT_PGPHOMEDIR}" - gpg="$(git config --get gpg.program || echo "gpg")" + gpg="$(git config --get gpg.program || printf '%s\n' "gpg")" cert="$(git cat-file blob "${GIT_PUSH_CERT}")" begin_sig="-----BEGIN PGP SIGNATURE-----" @@ -86,12 +86,12 @@ check_signed_push_keyring(){ cert_sig="${tmpdir}"/cert.sig in_sig=0 - echo "${cert}" | while read -r line; do + printf '%s\n' "${cert}" | while read -r line; do if test "${in_sig}" = "1" || test "${line}" = "${begin_sig}"; then in_sig=1 - echo "${line}" | tee -a "${cert_sig}" + printf '%s\n' "${line}" | tee -a "${cert_sig}" elif test "${line}" != "${begin_sig}"; then - echo "${line}" | tee -a "${cert_msg}" + printf '%s\n' "${line}" | tee -a "${cert_msg}" else break fi @@ -101,7 +101,7 @@ check_signed_push_keyring(){ --homedir "${GIT_PUSH_CERT_PGPHOMEDIR}" \ --verify "${cert_sig}" "${cert_msg}" 2>&1)" gpg_ec="$?" - gpg_sig="$(echo "${gpg_out}" | awk '/ GOODSIG /{print $3}')" + gpg_sig="$(printf '%s\n' "${gpg_out}" | awk '/ GOODSIG /{print $3}')" if test "${gpg_ec}" = "0"; then true "Cert validation succeeded. Key: ${gpg_sig}" else @@ -142,7 +142,8 @@ while read -r oldrev newrev ref; do continue fi commit_tag="$(git rev-list -n1 "${newrev}")" - obj_rejected="$(echo "${obj_rejected}" | sed -e "s/ ${commit_tag} //")" + obj_rejected="$(printf '%s\n' "${obj_rejected}" | \ + sed -e "s/ ${commit_tag} //")" err "Commit validation done by tag: ${commit_tag} ${newrev}" continue fi @@ -162,7 +163,7 @@ done test -n "${obj_rejected}" || exit 0 -obj_rejected="$(echo "${obj_rejected}" | tr -s " " | +obj_rejected="$(printf '%s\n' "${obj_rejected}" | tr -s " " | sed -e "s/^ //" -e "s/ $//")" err "Couldn't verify objects: ${obj_rejected}" exit 1 @@ -191,7 +192,8 @@ while read -r oldrev newrev ref; do continue fi commit_tag="$(git rev-list -n1 "${newrev}")" - obj_rejected="$(echo "${obj_rejected}" | sed -e "s/ ${commit_tag} //")" + obj_rejected="$(printf '%s\n' "${obj_rejected}" | \ + sed -e "s/ ${commit_tag} //")" err "Commit validation done by tag: ${commit_tag} ${newrev}" continue fi @@ -209,6 +211,7 @@ done test -n "${obj_rejected}" || exit 0 -obj_rejected="$(echo "${obj_rejected}" | tr -s " " | sed -e "s/^ //;s/ $//")" +obj_rejected="$(printf '%s\n' "${obj_rejected}" | tr -s " " | \ + sed -e "s/^ //;s/ $//")" err "Couldn't verify objects: ${obj_rejected}" exit 1 diff --git a/files/git/.config/git/template/hooks/prepare-commit-msg b/files/git/.config/git/template/hooks/prepare-commit-msg index 4ec772f..eccd014 100755 --- a/files/git/.config/git/template/hooks/prepare-commit-msg +++ b/files/git/.config/git/template/hooks/prepare-commit-msg @@ -14,7 +14,7 @@ file="$1" #commit_source="$2" #sha1="$3" -char="$(git config --get core.commentChar || echo "#")" +char="$(git config --get core.commentChar || printf '%s\n' "#")" template="$(git config --get commit.template | sed -e "s|^~/|${HOME}/|")" if test "${char}" = "auto"; then @@ -34,7 +34,7 @@ sed -i'' \ ## Replace init.template comment char to the core.commentChar line per line. if test -f "${template}"; then while read -r line; do - mod_line="$(echo "${line}" | sed -e "s/^. /${char} /")" + mod_line="$(printf '%s\n' "${line}" | sed -e "s/^. /${char} /")" sed -i'' -e "s/^${line}$/${mod_line}/" -- "${file}" done < "${template}" fi diff --git a/files/git/.local/bin/git-server-setup b/files/git/.local/bin/git-server-setup index bd2dd7f..62ec20c 100755 --- a/files/git/.local/bin/git-server-setup +++ b/files/git/.local/bin/git-server-setup @@ -9,7 +9,7 @@ set -eu uid="$(id -u)" if ! test "${uid}" = "0"; then - echo "This program requires root." >&2 + printf '%s\n' "This program requires root." >&2 exit 1 fi diff --git a/files/mutt/.local/bin/mutt-sorcerer b/files/mutt/.local/bin/mutt-sorcerer index a715c64..c7112b1 100755 --- a/files/mutt/.local/bin/mutt-sorcerer +++ b/files/mutt/.local/bin/mutt-sorcerer @@ -17,18 +17,18 @@ local_file="${HOME}/.muttrc.local" source_existent(){ for file in "${@}"; do if test -f "${file}"; then - echo source "\"${file}\"" + printf '%s\n' "source \"${file}\"" fi done unset file } ## Source files that must exist, let mutt fail otherwise. -echo source "\"${credentials_file}\"" +printf '%s\n' "source \"${credentials_file}\"" ## PWD is inherited from the muttrc that called this script. for file in *.muttrc; do - echo source "\"${file}\"" + printf '%s\n' "source \"${file}\"" done unset file diff --git a/files/qvm-copy-dotfiles b/files/qvm-copy-dotfiles index 73fa17b..3005368 100755 --- a/files/qvm-copy-dotfiles +++ b/files/qvm-copy-dotfiles @@ -14,16 +14,17 @@ ## sudo ./qvm-copy-dotfiles QUBE set -eu -test -n "${1:-}" || { echo "usage: ${0##*/} QUBE"; exit 1; } +test -n "${1:-}" || { printf '%s\n' "usage: ${0##*/} QUBE"; exit 1; } uid="$(id -u)" -test "${uid}" = "0" || { echo "Program requires root."; exit 1; } +test "${uid}" = "0" || { printf '%s\n' "Program requires root."; exit 1; } qube="${1-}" if ! qvm-check -- "${qube}" >/dev/null 2>&1; then - echo "VM doesn't exist: '${qube}'" + printf '%s\n' "VM doesn't exist: '${qube}'" exit 1 fi -test -f ./setup.sh || { echo "File doesn't exist: './setup.sh'"; exit 1; } +test -f ./setup.sh || + { printf '%s\n' "File doesn't exist: './setup.sh'"; exit 1; } if test "${qube}" = "dom0"; then sh ./dotfiles/setup.sh diff --git a/files/sh/.config/bash/bashrc b/files/sh/.config/bash/bashrc index f5acadd..0097fe6 100644 --- a/files/sh/.config/bash/bashrc +++ b/files/sh/.config/bash/bashrc @@ -43,7 +43,7 @@ _reset_line() { esac ## Credit: Can't find the source, posted on StackExchange or alike. ## Does not work well on Bash 5.0 and older. - bash_version_clean="$(echo "${BASH_VERSION%.*}" | tr -d ".")" + bash_version_clean="$(printf '%s\n' "${BASH_VERSION%.*}" | tr -d ".")" if test "${bash_version_clean}" -lt 51; then unset bash_version_clean return diff --git a/files/sh/.config/sh/profile b/files/sh/.config/sh/profile index 266a0ab..ea3a508 100644 --- a/files/sh/.config/sh/profile +++ b/files/sh/.config/sh/profile @@ -156,7 +156,7 @@ if test -z "${SSH_AUTH_SOCK-}" && has ssh-agent; then ssh_agent_env="$(ssh-agent -s -a "${ssh_agent_sock}")" eval "${ssh_agent_env}" >/dev/null unset ssh_agent_env - echo "${SSH_AGENT_PID}" | tee "${ssh_agent_pid}" >/dev/null + printf '%s\n' "${SSH_AGENT_PID}" | tee "${ssh_agent_pid}" >/dev/null fi fi unset ssh_agent_dir ssh_agent_sock ssh_agent_pid diff --git a/files/sh/.config/sh/shrc b/files/sh/.config/sh/shrc index d0f97eb..62b7622 100644 --- a/files/sh/.config/sh/shrc +++ b/files/sh/.config/sh/shrc @@ -186,7 +186,7 @@ if test "${color_prompt-}" = "yes"; then ## Fix bold on some terminals. case "${TERM-}" in xterm*|screen*) - LS_COLORS="$(echo "${LS_COLORS}" | sed -e 's/01;3/00;9/g')" + LS_COLORS="$(printf '%s\n' "${LS_COLORS}" | sed -e 's/01;3/00;9/g')" ;; *) ;; esac diff --git a/files/sh/.local/bin/has b/files/sh/.local/bin/has index 990ab7d..4efe9e0 100755 --- a/files/sh/.local/bin/has +++ b/files/sh/.local/bin/has @@ -20,7 +20,7 @@ action="" test -n "${1-}" || exit 1 case "$1" in -s) action=show; shift; test -n "${1-}" || exit 1;; - "") echo "Argument required" >&2; exit 1;; + "") printf '%s\n' "Argument required" >&2; exit 1;; *) ;; esac diff --git a/files/sh/.local/bin/resize-terminal b/files/sh/.local/bin/resize-terminal index d37e72d..c8f574e 100755 --- a/files/sh/.local/bin/resize-terminal +++ b/files/sh/.local/bin/resize-terminal @@ -15,6 +15,8 @@ fi test -t 0 || exit 0 +msg_unsupported="error: cannot resize screen: unsupported terminal emulator" + ## If argument is provided, allow user to bypass tty check. if test "${#}" -eq 0; then ## Shells on graphical sessions (terminal emulators) are skipped. @@ -46,7 +48,7 @@ fi ## POSIX compliant. # shellcheck disable=SC3045 -if ! echo R | read -r -t 1 -sd R 2>/dev/null; then +if ! printf '%s\n' "R" | read -r -t 1 -sd R 2>/dev/null; then ## Fast but depends on XTerm. if has resize; then resize_cmd="$(resize)" @@ -68,7 +70,7 @@ stty -echo printf '\e7\e[r\033[99999;99999H\e[6n\e8' >/dev/tty # shellcheck disable=3045,SC2034 IFS='[;R' read -r -t 1 -s -d R _ rows cols _ &2 + printf '%s\n' "${msg_unsupported}" >&2 stty echo unset rows cols exit 1 @@ -84,7 +86,7 @@ elif test "${rows}" -gt 0 && test "${cols}" -gt 0;then exit 0 fi -echo "error: cannot resize screen: unsupported terminal emulator" >&2 +printf '%s\n' "${msg_unsupported}" >&2 stty echo unset rows cols exit 1 diff --git a/files/tmux/.local/bin/tmux-sorcerer b/files/tmux/.local/bin/tmux-sorcerer index 0979056..cec6bbd 100755 --- a/files/tmux/.local/bin/tmux-sorcerer +++ b/files/tmux/.local/bin/tmux-sorcerer @@ -69,7 +69,7 @@ source_plugins(){ do plugin_name="${plugin##*/}" plugin_name="${plugin_name##tmux-}" - plugin_name="$(echo "${plugin_name}" | tr "-" "_")" + plugin_name="$(printf '%s\n' "${plugin_name}" | tr "-" "_")" plugin_script="${plugin}/${plugin_name}.tmux" test -r "${plugin_script}" || continue "${plugin_script}" >/dev/null 2>&1