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.
This commit is contained in:
Ben Grande 2024-08-06 17:27:08 +02:00
parent b38834d66b
commit d13a21a734
No known key found for this signature in database
GPG Key ID: 00C64E14F51F9E56
20 changed files with 57 additions and 50 deletions

View File

@ -6,7 +6,8 @@
set -eu 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="${*}" vms="${*}"

View File

@ -10,11 +10,11 @@
set -eu set -eu
if ! command -v sensors >/dev/null; then if ! command -v sensors >/dev/null; then
echo "Program not installed: sensors" >&2 printf '%s\n' "Program not installed: sensors" >&2
exit 1 exit 1
fi fi
if ! command -v xentop >/dev/null; then if ! command -v xentop >/dev/null; then
echo "Program not installed: xentop" >&2 printf '%s\n' "Program not installed: xentop" >&2
exit 1 exit 1
fi fi

View File

@ -24,7 +24,7 @@ _get-cword-pos() {
[[ ${COMP_WORDS[i]} == -* ]] && continue [[ ${COMP_WORDS[i]} == -* ]] && continue
((index++)) ((index++))
done done
echo ${index} printf '%s\n' "${index}"
} }
# Get the relative position of the first COMP_CWORD with option words ignored # Get the relative position of the first COMP_CWORD with option words ignored
@ -33,10 +33,10 @@ _get-first-cword() {
local i local i
for ((i=1; i<=COMP_CWORD; i++)); do for ((i=1; i<=COMP_CWORD; i++)); do
[[ ${COMP_WORDS[i]} == -* ]] && continue [[ ${COMP_WORDS[i]} == -* ]] && continue
echo "${COMP_WORDS[i]}" printf '%s\n' "${COMP_WORDS[i]}"
return 0 return 0
done done
echo "" printf '%s\n' ""
} }

View File

@ -71,16 +71,16 @@
add-unmerged = "!f() { git diff --name-status --diff-filter=U | cut -f2 ; }; git add $(f)" 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. ; List tips of branches that are not in the first arg.
; git tips origin/master ^origin/alternate | git oneline ; git tips origin/master ^origin/alternate | git oneline
oneline ="!_() { $(test $# -eq 0 && echo xargs -L1) git log --no-walk --decorate --oneline \"$@\"; }; _" 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 echo $t; _ \"$@\" ^$t; fi; }; _" tips = "!_() { t=$(git rev-list --no-merges --max-count=1 \"$@\"); if test -n \"$t\"; then printf '%s\n' \"$t\"; _ \"$@\" ^$t; fi; }; _"
; Submodules. ; Submodules.
sub-update = !sh -c 'git checkout $1 && git submodule update --recursive' sub-update = !sh -c 'git checkout $1 && git submodule update --recursive'
; Signed tags and commits ; Signed tags and commits
stag = "!sh -c 'commit_id=\"$(git rev-parse --verify \"$@\")\"; \ 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\" \ git tag -s \"$tag_name\" \
-m \"Tag for commit $commit_id\" \"$commit_id\"; \ -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) ptag = !git push $(git config branch.$(git branch --show-current).remote) $(git describe)
vtag = !git verify-tag -v $(git describe) vtag = !git verify-tag -v $(git describe)
vhci = !git verify-commit -v $(git rev-parse HEAD) vhci = !git verify-commit -v $(git rev-parse HEAD)

View File

@ -18,14 +18,14 @@ regex="^[A-Za-z0-9]+([A-Za-z0-9_.-]+[A-Za-z0-9]+)?$"
description_regex="^[A-Za-z0-9 _.-]+$" description_regex="^[A-Za-z0-9 _.-]+$"
fail_invalid_name(){ fail_invalid_name(){
echo "Error: invalid value for key: $1" >&2 printf '%s\n' "Error: invalid value for key: $1" >&2
exit 1 exit 1
} }
test_description(){ test_description(){
key="$1" key="$1"
value="$2" 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}" fail_invalid_name "${key}"
fi fi
} }
@ -33,7 +33,7 @@ test_description(){
test_name(){ test_name(){
key="$1" key="$1"
value="$2" 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}" fail_invalid_name "${key}"
fi fi
} }
@ -48,12 +48,12 @@ clean_repo_name(){
is_bare(){ is_bare(){
_repo="$1" _repo="$1"
if ! test -d "${_repo}"; then if ! test -d "${_repo}"; then
echo "Repository doesn't exist: ${_repo}" >&2 printf '%s\n' "Repository doesn't exist: ${_repo}" >&2
return 1 return 1
fi fi
bare_repo_check="$(git -C "${_repo}" rev-parse --is-bare-repository)" bare_repo_check="$(git -C "${_repo}" rev-parse --is-bare-repository)"
if ! test "${bare_repo_check}" = "true"; then 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 return 1
fi fi
} }

View File

@ -6,7 +6,7 @@
set -eu 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 shell access is not available. You have access to these repositories:" >&2
"${0%/*}"/list >&2 "${0%/*}"/list >&2

View File

@ -11,7 +11,7 @@ set -eu
usage(){ usage(){
# shellcheck disable=2154 # 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 note: prints the current description if none description is specified.:w
regex: ${regex}" >&2 regex: ${regex}" >&2
exit 1 exit 1
@ -35,7 +35,7 @@ if test -z "${3-}"; then
exit 0 exit 0
fi fi
description="$(echo "$3" | cut -c 1-80)" description="$(printf '%s\n' "$3" | cut -c 1-80)"
test_description description "${description}" test_description description "${description}"
echo "${description}" | tee "${description_file}" printf '%s\n' "${description}" | tee "${description_file}"

View File

@ -11,7 +11,7 @@ set -eu
usage(){ usage(){
# shellcheck disable=2154 # shellcheck disable=2154
echo "usage: ${0##*/} SECTION REPOSITORY [BRANCH] printf '%s\n' "usage: ${0##*/} SECTION REPOSITORY [BRANCH]
regex: ${regex}" >&2 regex: ${regex}" >&2
exit 1 exit 1
} }

View File

@ -14,7 +14,7 @@ set -eu
usage(){ usage(){
# shellcheck disable=2154 # shellcheck disable=2154
echo "usage: ${0##*/} [SECTION] printf '%s\n' "usage: ${0##*/} [SECTION]
regex: ${regex}" >&2 regex: ${regex}" >&2
exit 1 exit 1
} }
@ -28,7 +28,7 @@ esac
# shellcheck disable=SC2154 # shellcheck disable=SC2154
if ! test -d "${base}/${section}"; then if ! test -d "${base}/${section}"; then
echo "Section doesn't exist: ${section}" >&2 printf '%s\n' "Section doesn't exist: ${section}" >&2
exit 1 exit 1
fi fi

View File

@ -41,7 +41,7 @@ tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/XXXXXX")"
trap 'rm -f "${tmpdir}"' HUP INT QUIT ABRT TERM EXIT trap 'rm -f "${tmpdir}"' HUP INT QUIT ABRT TERM EXIT
err(){ err(){
echo "${*}" >&2 printf '%s\n' "${*}" >&2
} }
require_signed_push(){ require_signed_push(){
@ -78,7 +78,7 @@ check_signed_push(){
check_signed_push_keyring(){ check_signed_push_keyring(){
true "Using keyring to verify push certificate: ${GIT_PUSH_CERT_PGPHOMEDIR}" 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}")" cert="$(git cat-file blob "${GIT_PUSH_CERT}")"
begin_sig="-----BEGIN PGP SIGNATURE-----" begin_sig="-----BEGIN PGP SIGNATURE-----"
@ -86,12 +86,12 @@ check_signed_push_keyring(){
cert_sig="${tmpdir}"/cert.sig cert_sig="${tmpdir}"/cert.sig
in_sig=0 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 if test "${in_sig}" = "1" || test "${line}" = "${begin_sig}"; then
in_sig=1 in_sig=1
echo "${line}" | tee -a "${cert_sig}" printf '%s\n' "${line}" | tee -a "${cert_sig}"
elif test "${line}" != "${begin_sig}"; then elif test "${line}" != "${begin_sig}"; then
echo "${line}" | tee -a "${cert_msg}" printf '%s\n' "${line}" | tee -a "${cert_msg}"
else else
break break
fi fi
@ -101,7 +101,7 @@ check_signed_push_keyring(){
--homedir "${GIT_PUSH_CERT_PGPHOMEDIR}" \ --homedir "${GIT_PUSH_CERT_PGPHOMEDIR}" \
--verify "${cert_sig}" "${cert_msg}" 2>&1)" --verify "${cert_sig}" "${cert_msg}" 2>&1)"
gpg_ec="$?" 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 if test "${gpg_ec}" = "0"; then
true "Cert validation succeeded. Key: ${gpg_sig}" true "Cert validation succeeded. Key: ${gpg_sig}"
else else
@ -142,7 +142,8 @@ while read -r oldrev newrev ref; do
continue continue
fi fi
commit_tag="$(git rev-list -n1 "${newrev}")" 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}" err "Commit validation done by tag: ${commit_tag} ${newrev}"
continue continue
fi fi
@ -162,7 +163,7 @@ done
test -n "${obj_rejected}" || exit 0 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/ $//")" sed -e "s/^ //" -e "s/ $//")"
err "Couldn't verify objects: ${obj_rejected}" err "Couldn't verify objects: ${obj_rejected}"
exit 1 exit 1
@ -191,7 +192,8 @@ while read -r oldrev newrev ref; do
continue continue
fi fi
commit_tag="$(git rev-list -n1 "${newrev}")" 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}" err "Commit validation done by tag: ${commit_tag} ${newrev}"
continue continue
fi fi
@ -209,6 +211,7 @@ done
test -n "${obj_rejected}" || exit 0 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}" err "Couldn't verify objects: ${obj_rejected}"
exit 1 exit 1

View File

@ -14,7 +14,7 @@ file="$1"
#commit_source="$2" #commit_source="$2"
#sha1="$3" #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}/|")" template="$(git config --get commit.template | sed -e "s|^~/|${HOME}/|")"
if test "${char}" = "auto"; then if test "${char}" = "auto"; then
@ -34,7 +34,7 @@ sed -i'' \
## Replace init.template comment char to the core.commentChar line per line. ## Replace init.template comment char to the core.commentChar line per line.
if test -f "${template}"; then if test -f "${template}"; then
while read -r line; do 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}" sed -i'' -e "s/^${line}$/${mod_line}/" -- "${file}"
done < "${template}" done < "${template}"
fi fi

View File

@ -9,7 +9,7 @@ set -eu
uid="$(id -u)" uid="$(id -u)"
if ! test "${uid}" = "0"; then if ! test "${uid}" = "0"; then
echo "This program requires root." >&2 printf '%s\n' "This program requires root." >&2
exit 1 exit 1
fi fi

View File

@ -17,18 +17,18 @@ local_file="${HOME}/.muttrc.local"
source_existent(){ source_existent(){
for file in "${@}"; do for file in "${@}"; do
if test -f "${file}"; then if test -f "${file}"; then
echo source "\"${file}\"" printf '%s\n' "source \"${file}\""
fi fi
done done
unset file unset file
} }
## Source files that must exist, let mutt fail otherwise. ## 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. ## PWD is inherited from the muttrc that called this script.
for file in *.muttrc; do for file in *.muttrc; do
echo source "\"${file}\"" printf '%s\n' "source \"${file}\""
done done
unset file unset file

View File

@ -14,16 +14,17 @@
## sudo ./qvm-copy-dotfiles QUBE ## sudo ./qvm-copy-dotfiles QUBE
set -eu 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)" 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-}" qube="${1-}"
if ! qvm-check -- "${qube}" >/dev/null 2>&1; then 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 exit 1
fi 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 if test "${qube}" = "dom0"; then
sh ./dotfiles/setup.sh sh ./dotfiles/setup.sh

View File

@ -43,7 +43,7 @@ _reset_line() {
esac esac
## Credit: Can't find the source, posted on StackExchange or alike. ## Credit: Can't find the source, posted on StackExchange or alike.
## Does not work well on Bash 5.0 and older. ## 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 if test "${bash_version_clean}" -lt 51; then
unset bash_version_clean unset bash_version_clean
return return

View File

@ -156,7 +156,7 @@ if test -z "${SSH_AUTH_SOCK-}" && has ssh-agent; then
ssh_agent_env="$(ssh-agent -s -a "${ssh_agent_sock}")" ssh_agent_env="$(ssh-agent -s -a "${ssh_agent_sock}")"
eval "${ssh_agent_env}" >/dev/null eval "${ssh_agent_env}" >/dev/null
unset ssh_agent_env 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
fi fi
unset ssh_agent_dir ssh_agent_sock ssh_agent_pid unset ssh_agent_dir ssh_agent_sock ssh_agent_pid

View File

@ -186,7 +186,7 @@ if test "${color_prompt-}" = "yes"; then
## Fix bold on some terminals. ## Fix bold on some terminals.
case "${TERM-}" in case "${TERM-}" in
xterm*|screen*) 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 esac

View File

@ -20,7 +20,7 @@ action=""
test -n "${1-}" || exit 1 test -n "${1-}" || exit 1
case "$1" in case "$1" in
-s) action=show; shift; test -n "${1-}" || exit 1;; -s) action=show; shift; test -n "${1-}" || exit 1;;
"") echo "Argument required" >&2; exit 1;; "") printf '%s\n' "Argument required" >&2; exit 1;;
*) ;; *) ;;
esac esac

View File

@ -15,6 +15,8 @@ fi
test -t 0 || exit 0 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 argument is provided, allow user to bypass tty check.
if test "${#}" -eq 0; then if test "${#}" -eq 0; then
## Shells on graphical sessions (terminal emulators) are skipped. ## Shells on graphical sessions (terminal emulators) are skipped.
@ -46,7 +48,7 @@ fi
## POSIX compliant. ## POSIX compliant.
# shellcheck disable=SC3045 # 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. ## Fast but depends on XTerm.
if has resize; then if has resize; then
resize_cmd="$(resize)" resize_cmd="$(resize)"
@ -68,7 +70,7 @@ stty -echo
printf '\e7\e[r\033[99999;99999H\e[6n\e8' >/dev/tty printf '\e7\e[r\033[99999;99999H\e[6n\e8' >/dev/tty
# shellcheck disable=3045,SC2034 # shellcheck disable=3045,SC2034
IFS='[;R' read -r -t 1 -s -d R _ rows cols _ </dev/tty || { IFS='[;R' read -r -t 1 -s -d R _ rows cols _ </dev/tty || {
echo "error: cannot resize screen: unsupported terminal emulator" >&2 printf '%s\n' "${msg_unsupported}" >&2
stty echo stty echo
unset rows cols unset rows cols
exit 1 exit 1
@ -84,7 +86,7 @@ elif test "${rows}" -gt 0 && test "${cols}" -gt 0;then
exit 0 exit 0
fi fi
echo "error: cannot resize screen: unsupported terminal emulator" >&2 printf '%s\n' "${msg_unsupported}" >&2
stty echo stty echo
unset rows cols unset rows cols
exit 1 exit 1

View File

@ -69,7 +69,7 @@ source_plugins(){
do do
plugin_name="${plugin##*/}" plugin_name="${plugin##*/}"
plugin_name="${plugin_name##tmux-}" 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" plugin_script="${plugin}/${plugin_name}.tmux"
test -r "${plugin_script}" || continue test -r "${plugin_script}" || continue
"${plugin_script}" >/dev/null 2>&1 "${plugin_script}" >/dev/null 2>&1