Re:Bash functions are better than I thought
by databasher on Sunday October 31, 2021 @11:40PM
(#29062791)
Bash `getopts` handles short and long arguments gnu-style without any problem. The following code handles args like "-h", "-i $input-file", "-i$input-file", "--in=$input-file", and "--help":
while getopts :i:h-: option
do case $option in
# accept -i $input-file, -i$input-file
i ) input_file=$OPTARG;;
h ) print_help;;
- ) case $OPTARG in
help ) print_help;;
help=* ) echo "Option has unexpected argument: ${OPTARG%%=*}" >&2; exit 1;;
in=* ) input_file=${OPTARG##*=};;
in ) echo "Option missing argument: $OPTARG" >&2; exit 1;;
* ) echo "Bad option $OPTARG" >&2; exit 1;;
esac;;
'?' ) echo "Unknown option $OPTARG" >&2; exit 1;;
: ) echo "Option missing argument: $OPTARG" >&2; exit 1;;
* ) echo "Bad state in getopts" >&2; exit 1;;
esac
done
shift $((OPTIND-1))
Re:Bash functions are better than I thought
by drran on Sunday October 31, 2021 @06:57PM
(#29061295)
You can use bash-modules arguments library to generate argument parser for you.
Re:Bash functions are better than I thought
by MereInterest on Sunday October 31, 2021 @07:25PM
(#29061463)
Thank you, I haven't heard of that one before. However, all the examples look like it gets called as an external library, which would either need to be distributed with a script, or to already be installed by a user.
Is there a feature I'm not seeing that would generate an argument parser without external dependencies?
Re:Bash functions are better than I thought
by drran on Monday November 01, 2021 @05:24AM
(#29064527)
Yes, arguments::generate_parser function. Install bash-modules, then run `. import.sh log arguments`, then call `arguments::generate_parser '--foo)FOO;String'` , and it will generate function with parser, which include parser for foo option for both `--foo VALUE` and `--foo=VALUE`:
...
--foo)
FOO="${2:?ERROR: String value is required for \"-f|--foo\" option. See --help for details.}"
shift 2
;;
--foo=*)
FOO="${1#*=}"
shift 1
;;
...
Parsing command-line arguments is easy, but parsing them correctly is ridiculously hard. `getopts` doesn't handle long flags, so it's out. `getopt` doesn't handle arguments with spaces in them, unless you have a version with non-standard extensions, so it's out. You're left with manual parsing, and it's a royal pain to make sure you handle every expected case (short/long flags, clusters of short flags, trailing arguments to be passed through to a subprocess, short/long options whose value is in the next argument, long options whose value is after an equals sign, and several others I'm probably forgetting about). And this is just to get the arguments into your script, before you actually do anything with it.
I agree that bash has effective idioms, and learning those idioms can make scripts easier to write. I strongly disagree that bash is "as maintainable as anything else", and scripts beyond a few hundred lines should be rewritten before they can continue growing.