Road to POSIX
Howdy :wave:
Been a hot minute. I've returned with a scratch at the surface towards converting the notify-send.sh script into a POSIX shell-compliant one. This first batch of changes covers conditional constructs.
BASH is quite comfortable and offers a series of things POSIX shell does not, such as convenient extended regular expression matching. POSIX shell is fairly poorer in this regard, but functionally equivalent alternatives exist. Here is my first proposal. It is a relatively substantial one, but I thought it would be best to break things into what I consider feature-set disparities between BASH and POSIX shell.
I'm creating a draft PR so this can be further discussed before it can be promoted to a proper PR and be more thoroughly tested as well.
Oh, as an added note, instead of using cases for some of the pattern matching, one could resort to expr(1p).
edit: in fact, just a bit of exploration lead me to an interesting and clearer alternative for matching numeric values using expr.
expr "$variable" : '-\{,1\}[[:digit:]]\{1,\}$'
One can already notice the anchor $ at the end, but a missing ^ at the beginning. As per expr(1p):
EXTENDED DESCRIPTION
...
Matching Expression
...... <initial excerpt of paragraph omitted for brevity's sake> ...... Regular expression syn‐
tax shall be that defined in the Base Definitions volume of POSIX.1‐2017, Section 9.3, Basic
Regular Expressions, except that all patterns are anchored to the beginning of the string (that
is, only sequences starting at the first character of a string are matched by the regular ex‐
pression) and, therefore, it is unspecified whether '^' is a special character in that context.
...
The pattern, broken down:
- # the '-' literal
\{,1\} # at most once (= <obj>?)
[[:digit:]] # decimal digit character class
\{1,\} # at least once (= <obj>+ or <obj><obj>*)
$ # end anchor
which is equivalent to the expression already used in the script (/^-?[0-9]+$/).
Here are a quick couple of (paranoia satiation) tests;
$ pat='-\{,1\}[[:digit:]]\{1,\}$'
$ expr '1234' : "$pat"
4 # number of characters matched
$ expr '-1234' : "$pat"
5
$ expr ' 1234' : "$pat"
0
$ expr 'aaa1234' : "$pat"
0
$ expr '1234aaa' : "$pat"
0
$ expr '1234 ' : "$pat"
0
$ expr '-1234 ' : "$pat"
0
$ expr '-12aa34' : "$pat"
0
Here's an example pitting case vs. expr:
case ${variable#-} in
*[![:digit:]]*) echo "not ok"; exit 1 ;;
esac
# versus
if expr "$variable" : '-\{,1\}[[:digit:]]\{1,\}' = 0; then
echo "not ok"
exit 1
fi
It's a matter of wanting to do it using pure shell or resorting to expr.
hmmm, at a glance it looks good, tho for some of the still hard regex stuff what do you think about using some awk magic?
iirc the one true awk that should be standar for POSIX supports a rather nice subset of regex so it can be abused on functions to pass it some input and then pour awk's output into other functions and vars.