>>> Martin D Kealey <mar...@kurahaupo.gen.nz> schrieb am 03.12.2022 um 02:26 in Nachricht <CAN_U6MVDGDapEmqKqaqE5A=hte7v9suqqt7ybsj2kcle+ob...@mail.gmail.com>:
... > Found in the real code (intended to trigger a bug): >> declare ERRORS=0 ARGS=$(getopt -o "$S_OPTS" -l "$L_OPTS" -n "$0" -- >> "$@") >> > if [ $? -ne 0 ]; then >> usage >> fi >> > > That is a well-known anti-pattern that should be avoided. > > Some working equivalents would be: > ``` > declare ARGS=$( getopt -o "$S_OPTS" -l "$L_OPTS" -n "$0" -- "$@" ) > ERRORS=$? > (( ERRORS == 0 )) || usage > ``` > or: > ``` > declare ARGS ERRORS=0 > ARGS=$( getopt -o "$S_OPTS" -l "$L_OPTS" -n "$0" -- "$@" ) || > usage > ``` > > -Martin > > (PS: "Working" would be questionable, since putting `getopt` in a subshell > prevents it from updating "$@"; and `test $? = 0` and its variants are > pointless clutter.) Well, the code proved to work, and the pattern was found in /usr/share/getopt/getopt-parse.bash (of BASH 4.3): ... # Note that we use "$@" to let each command-line parameter expand to a # separate word. The quotes around "$@" are essential! # We need TEMP as the 'eval set --' would nuke the return value of getopt. TEMP=$(getopt -o 'ab:c::' --long 'a-long,b-long:,c-long::' -n 'example.bash' -- "$@") if [ $? -ne 0 ]; then echo 'Terminating...' >&2 exit 1 fi ...