In spite of all the POSIX shell disadvantages, I am still sticking with it and I love its portability.
Recently, I was searching for a way of code re-use, which turns out to be structured programming and input validation = Yes, in a POSIX shell script.
Let me begin with the simpler.
is_integer()
+ is_exit_code()
is_integer ()
{
case "${1#[+-]}" in
(*[!0123456789]*) return 1 ;;
('') return 1 ;;
(*) return 0 ;;
esac
}
is_exit_code ()
{
is_integer "$1" &&
case "$1" in
([+-]*) return 1 ;;
esac &&
[ "$1" -le 255 ]
}
Here, I continue on with further chained functions.
print_error()
+ print_error__exit()
print_error ()
{
if ! { [ $# -eq 2 ] && [ -n "$1" ] && [ -n "$2" ]; } then
printf '%b\n' "Some longer error message."
exit 1
fi
printf '%b\n' \
"${color_red}Error occurred$tput_reset" \
"Error heading: $color_yellow$1$tput_reset" \
"Error message: $2"
} >&2
print_error__exit ()
{
if ! { [ $# -eq 2 ] && [ -n "$1" ] && [ -n "$2" ]; } &&
! { [ $# -eq 3 ] && [ -n "$1" ] && [ -n "$2" ] && is_exit_code "$3" && [ "$3" -ge 1 ]; } then
printf '%b\n' "Some longer error message."
exit 1
fi
print_error "$1" "$2"
exit "${3:-1}"
} >&2
So, in this bare example, the chains go up like this:
print_error__exit ()
🠆print_error ()
;print_error__exit ()
🠆is_exit_code ()
🠆is_integer ()
.
Despite I am quite confident, these examples work as they should, one never knows, a maybe different point of view would shed a different light on my process.