2
\$\begingroup\$

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_yellow1ドル$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:

  1. print_error__exit () 🠆 print_error ();

  2. 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.

asked Dec 3, 2020 at 7:49
\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

Your code looks nice. I give some additional advice.

  1. You can debug by calling the source command in your terminal (REPL).
  2. You can divide the common codes and the main codes by writing the source in the main code.
  3. Take care of an enormous number. The number 99999999999999999999999999999999999999999999999999, and so on.
  4. The action of writing some function is not functional programming but structured programming. The functional programming paradigm is like the idea of stream and pipe. Then, if you do not know functional programming, you may practice functional programming.
Toby Speight
87.1k14 gold badges104 silver badges322 bronze badges
answered May 30, 2021 at 5:40
\$\endgroup\$
0
2
\$\begingroup\$

In spite of all the POSIX shell disadvantages, I am still sticking with it and I love its portability.

You will come to realize that adhering to POSIX for your shell scripts is more often an advantage than a disadvantage. The reason the UNIX shells and utilities are powerful is because they standardized on the pipeline API and generally followed some vague conventions regarding exit status and commandline options. What the other UNIX shells added on top of the POSIX shell baseline are either anti-features or inconsequential enough to not be worth sacrificing portability for. Remember that Perl is a natural extension of the UNIX shells, so what most of these shell extensions achieve is nothing but an inferior Perl. The traditional UNIX shells are a dead end and should be considered to be on eternal life support.

PowerShell improved on the traditional UNIX shells by also standardizing on the commandline options and input and output format, bringing structure to the arbitrary text passed around in the UNIX shells. In theory and based on technical merits alone, PowerShell should be the next in line in the evolution of UNIX shells, but as it failed to successfully assimilate the strengths of the UNIX shells with its own strengths due to major design flaws and a spotty implementation, it is in fact a big step backward in some aspects.


It is a very good idea to do input validation. To see why, read Mr Chazelas's answer where he also provides an implementation of the is_integer function. Stéphane Chazelas is, amongst other specialties, a shell programming guru and the discoverer of the initial Shellshock vulnerabilities, so his code is often worth studying and copying (with proper attributions of course).

For your is_exit_code function implementation, note that in the latest POSIX.1-2024, the shell exit status is permitted to be greater than 255 in certain circumstances:

  • Otherwise, if the command terminated due to the receipt of a signal, the shell shall assign it an exit status greater than 128. The exit status shall identify, in an implementation-defined manner, which signal terminated the command. Note that shell implementations are permitted to assign an exit status greater than 255 if a command terminates due to a signal.

I think ksh is one such shell implementation that can return an exit status greater than 255, if you're curious.

By the way, it is better to quote the $# variable since it can be more than a single digit and the IFS can be set to a number. One can rarely be too careful (though there are a few exceptions) when it comes to quoting in shell scripts.

Why does your print_error__exit function have two underscores in the name?

answered Aug 12 at 5:53
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.