Skip to content

Commit

Permalink
merge branch "improve robustness/portability 💪" into dev-2.x :
Browse files Browse the repository at this point in the history
- use `printf` 💪 instead of `echo`
  - the `echo` option(e.g. -e -n) may effect correctness, `printf` is more robust 💪
- use `if-else` instead of `&&-||`
  - about `&&-||` see shell check:
    https://www.shellcheck.net/wiki/SC2015
- small improvement/refactor
  • Loading branch information
oldratlee committed Sep 3, 2023
2 parents 84b6218 + 0942d59 commit 1c672bb
Show file tree
Hide file tree
Showing 14 changed files with 367 additions and 222 deletions.
34 changes: 15 additions & 19 deletions bin/a2l
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
# @Function
# echo each arguments on one line colorfully.
# print each arguments on one line colorfully.
#
# @Usage
# $ ./a2l arg1 arg2
Expand All @@ -19,26 +19,22 @@ readonly PROG_VERSION='2.5.0-dev'
# util functions
################################################################################

# NOTE: $'foo' is the escape sequence syntax of bash
readonly ec=$'\033' # escape char
readonly eend=$'\033[0m' # escape end

colorEcho() {
colorPrint() {
local color="$1"
shift
# check isatty in bash https://stackoverflow.com/questions/10022323
# if stdout is console, turn on color output.
[ -t 1 ] && echo "${ec}[1;${color}m$*${eend}" || echo "$*"
}

redEcho() {
colorEcho 31 "$@"
if [ -t 1 ]; then
printf "\033[1;${color}m%s\033[0m\n" "$*"
else
printf '%s\n' "$*"
fi
}

usage() {
cat <<EOF
Usage: ${PROG} [OPTION]... ARG...
echo each arguments on one line colorfully.
print each arguments on one line colorfully.
Example:
${PROG} arg1 arg2
Expand All @@ -53,7 +49,7 @@ EOF
}

progVersion() {
echo "$PROG $PROG_VERSION"
printf '%s\n' "$PROG $PROG_VERSION"
exit
}

Expand Down Expand Up @@ -94,20 +90,20 @@ readonly args
# biz logic
################################################################################

readonly -a ECHO_COLORS=(33 35 36 31 32 37 34)
readonly -a ROTATE_COLORS=(33 35 36 31 32 37 34)
COUNT=0
rotateColorEcho() {
rotateColorPrint() {
local message="$*"

# skip color for white space
if [[ "$message" =~ ^[[:space:]]*$ ]]; then
echo "$message"
printf '%s\n' "$message"
else
local color="${ECHO_COLORS[COUNT++ % ${#ECHO_COLORS[@]}]}"
colorEcho "$color" "$*"
local color="${ROTATE_COLORS[COUNT++ % ${#ROTATE_COLORS[@]}]}"
colorPrint "$color" "$*"
fi
}

for a in ${args[@]:+"${args[@]}"}; do
rotateColorEcho "$a"
rotateColorPrint "$a"
done
55 changes: 35 additions & 20 deletions bin/ap
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,24 @@ readonly PROG_VERSION='2.5.0-dev'
# util functions
################################################################################

# NOTE: $'foo' is the escape sequence syntax of bash
readonly ec=$'\033' # escape char
readonly eend=$'\033[0m' # escape end
readonly nl=$'\n' # new line

colorEcho() {
colorPrint() {
local color="$1"
shift
# check isatty in bash https://stackoverflow.com/questions/10022323
# if stdout is console, turn on color output.
[ -t 1 ] && echo "${ec}[1;${color}m$*${eend}" || echo "$*"
if [ -t 1 ]; then
printf "\033[1;${color}m%s\033[0m\n" "$*"
else
printf '%s\n' "$*"
fi
}

redEcho() {
colorEcho 31 "$@"
redPrint() {
colorPrint 31 "$*"
}

die() {
redEcho "Error: $*" 1>&2
redPrint "Error: $*" >&2
exit 1
}

Expand All @@ -54,10 +53,15 @@ portableReadLink() {
readlink -f "$file"
;;
Darwin*)
local py_args=(-c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$file")
if command -v greadlink >/dev/null; then
greadlink -f "$file"
elif command -v python3 >/dev/null; then
python3 "${py_args[@]}"
elif command -v python >/dev/null; then
python "${py_args[@]}"
else
python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$file"
die "fail to find command(greadlink/python3/python) to get absolute path!"
fi
;;
*)
Expand All @@ -72,10 +76,12 @@ usage() {
# shellcheck disable=SC2015
[ "$exit_code" != 0 ] && local -r out=/dev/stderr || local -r out=/dev/stdout

(($# > 0)) && redEcho "$*$nl" >$out
# NOTE: $'foo' is the escape sequence syntax of bash
local nl=$'\n' # new line
(($# > 0)) && redPrint "$*$nl" >$out

cat >$out <<EOF
Usage: ${PROG} [OPTION]... ARG...
Usage: ${PROG} [OPTION]... [FILE]...
convert to Absolute Path.
Example:
Expand All @@ -91,7 +97,7 @@ EOF
}

progVersion() {
echo "$PROG $PROG_VERSION"
printf '%s\n' "$PROG $PROG_VERSION"
exit
}

Expand All @@ -115,7 +121,6 @@ while [ $# -gt 0 ]; do
;;
-*)
usage 2 "${PROG}: unrecognized option '$1'"
break
;;
*)
# if not option, treat all follow files as args
Expand All @@ -128,10 +133,20 @@ done
[ ${#files[@]} -eq 0 ] && files=(.)
readonly files

################################################################################
# biz logic
################################################################################

has_error=false

for f in "${files[@]}"; do
! [ -e "$f" ] && {
echo "$f does not exists!"
continue
}
portableReadLink "$f"
if [ -e "$f" ]; then
portableReadLink "$f"
else
redPrint "error: $f does not exists!" >&2
has_error=true
fi
done

# set exit status
! $has_error
20 changes: 11 additions & 9 deletions bin/c
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ readonly PROG_VERSION='2.5.0-dev'
# util functions
################################################################################

readonly ec=$'\033' # escape char
readonly eend=$'\033[0m' # escape end
readonly nl=$'\n' # new line

redEcho() {
[ -t 1 ] && echo "${ec}[1;31m$*$eend" || echo "$*"
printErrorMsg() {
# check isatty in bash https://stackoverflow.com/questions/10022323
# if stdout is console, print with red color.
if [ -t 1 ]; then
printf "\033[1;31m%s\033[0m\n\n" "Error: $*"
else
printf '%s\n\n' "Error: $*"
fi
}

usage() {
Expand All @@ -49,7 +51,7 @@ usage() {
# shellcheck disable=SC2015
[ "$exit_code" != 0 ] && local -r out=/dev/stderr || local -r out=/dev/stdout

(($# > 0)) && redEcho "$*$nl" >$out
(($# > 0)) && printErrorMsg "$*" >$out

cat >$out <<EOF
Usage: ${PROG} [OPTION]... [command [command_args ...]]
Expand All @@ -73,7 +75,7 @@ EOF
}

progVersion() {
echo "$PROG $PROG_VERSION"
printf '%s\n' "$PROG $PROG_VERSION"
exit
}

Expand Down Expand Up @@ -106,7 +108,7 @@ while [ $# -gt 0 ]; do
break
;;
-*)
usage 2 "${PROG}: unrecognized option '$1'"
usage 2 "unrecognized option '$1'"
;;
*)
# if not option, treat all follow args as command
Expand Down
16 changes: 6 additions & 10 deletions bin/coat
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,22 @@ set -eEuo pipefail
# check isatty in bash https://stackoverflow.com/questions/10022323
[ ! -t 1 ] && exec cat "$@"

# NOTE: $'foo' is the escape sequence syntax of bash
readonly ec=$'\033' # escape char
readonly eend=$'\033[0m' # escape end

readonly -a ECHO_COLORS=(33 35 36 31 32 37 34)
readonly -a ROTATE_COLORS=(33 35 36 31 32 37 34)
COUNT=0
rotateColorEcho() {
rotateColorPrint() {
local message="$*"

# skip color for white space
if [[ "$message" =~ ^[[:space:]]*$ ]]; then
echo "$message"
printf '%s\n' "$message"
else
local color="${ECHO_COLORS[COUNT++ % ${#ECHO_COLORS[@]}]}"
echo "${ec}[1;${color}m$message$eend"
local color="${ROTATE_COLORS[COUNT++ % ${#ROTATE_COLORS[@]}]}"
printf "\033[1;${color}m%s\033[0m\n" "$message"
fi
}

# Bash read line does not read leading spaces
# https://stackoverflow.com/questions/29689172
cat "$@" | while IFS= read -r line; do
rotateColorEcho "$line"
rotateColorPrint "$line"
done
30 changes: 18 additions & 12 deletions bin/cp-into-docker-run
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,17 @@ readonly PROG_VERSION='2.5.0-dev'
# util functions
################################################################################

# NOTE: $'foo' is the escape sequence syntax of bash
readonly ec=$'\033' # escape char
readonly eend=$'\033[0m' # escape end
readonly nl=$'\n' # new line

redEcho() {
redPrint() {
# -t check: is a terminal device?
[ -t 1 ] && echo "${ec}[1;31m$*$eend" || echo "$*"
if [ -t 1 ]; then
printf "\033[1;31m%s\033[0m\n" "$*"
else
printf '%s\n' "$*"
fi
}

die() {
redEcho "Error: $*" 1>&2
redPrint "Error: $*" 1>&2
exit 1
}

Expand All @@ -47,10 +46,15 @@ portableReadLink() {
readlink -f "$file"
;;
Darwin*)
local py_args=(-c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$file")
if command -v greadlink >/dev/null; then
greadlink -f "$file"
elif command -v python3 >/dev/null; then
python3 "${py_args[@]}"
elif command -v python >/dev/null; then
python "${py_args[@]}"
else
python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$file"
die "fail to find command(greadlink/python3/python) for readlink!"
fi
;;
*)
Expand All @@ -65,7 +69,9 @@ usage() {
# shellcheck disable=SC2015
[ "$exit_code" != 0 ] && local -r out=/dev/stderr || local -r out=/dev/stdout

(($# > 0)) && redEcho "$*$nl" >$out
# NOTE: $'foo' is the escape sequence syntax of bash
local nl=$'\n' # new line
(($# > 0)) && redPrint "$*$nl" >$out

cat >$out <<EOF
Usage: ${PROG} [OPTION]... command [command-args]...
Expand Down Expand Up @@ -100,7 +106,7 @@ EOF
}

progVersion() {
echo "$PROG $PROG_VERSION"
printf '%s\n' "$PROG $PROG_VERSION"
exit
}

Expand Down Expand Up @@ -235,7 +241,7 @@ trap cleanupWhenExit EXIT
########################################

logAndRun() {
$verbose && echo "[$PROG] $*" 1>&2
$verbose && printf '%s\n' "[$PROG] $*" 1>&2
"$@"
}

Expand Down
35 changes: 26 additions & 9 deletions bin/echo-args
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,37 @@
# @author Jerry Lee (oldratlee at gmail dot com)
set -eEuo pipefail

readonly ec=$'\033' # escape char
readonly eend=$'\033[0m' # escape end
digitCount() {
# argument 1(num) is always a non-negative integer in this script usage,
# so NO argument validation logic.
local num="$1" count=0
while ((num != 0)); do
((++count))
((num = num / 10))
done
echo "$count"
}

digit_count=$(digitCount $#)
readonly arg_count=$# digit_count

readonly red='\033[1;31m'
readonly blue='\033[1;36m'
readonly normal='\033[0m'

echoArg() {
local index="$1" count="$2" value="$3"
printArg() {
local idx="$1" value="$2"

# if stdout is console, turn on color output.
[ -t 1 ] &&
echo "${index}/${count}: ${ec}[1;31m[$eend${ec}[1;36;40m$value$eend${ec}[1;31m]$eend" ||
echo "${index}/${count}: [${value}]"
if [ -t 1 ]; then
printf "%${digit_count}s/%s: ${red}[${blue}%s${red}]${normal}\n" "$idx" "$arg_count" "$value"
else
printf "%${digit_count}s/%s: [%s]\n" "$idx" "$arg_count" "$value"
fi
}

echoArg 0 $# "$0"
printArg 0 "$0"
idx=1
for a; do
echoArg $((idx++)) $# "$a"
printArg $((idx++)) "$a"
done
Loading

0 comments on commit 1c672bb

Please sign in to comment.