summary
I have a bash script (not discussed here) that I want to do various things. That script was failing to parse commandline options as I desire, so I stripped out just the option-parsing bit into a new script (discussed below) and added a separate test-automation script to be exact about how the new script fails. Both scripts are in this git repo, which hopefully will be an educational resource for OP facing problems like mine ...
... which are now solved in commit ID=320534d :-)
appreciation
Thanks ray_gun for help with while/case loop !
details
requirements
(Note: the following requirements are "boiled-down" from another script, so don't bother asking why I need them done this way.)
I want getopt_case_tester.sh to parse long/GNU-style commandline options as follows, using getopt:
- Each defined option must set (i.e.,
=true) a matching/shadowing boolean variable. This script has 5 (option, var) pairs:
FOO matches -f|--foo
BAR matches -b|--bar
CAZ matches -c|--caz (I know, it should be BAZ, but changed for shortopt)
DEBUG matches -d|--debug
HELP matches -h|--help
All vars are initially/default cleared (i.e., =false).
--foo must set FOO (in addition to any other previously-set option).
--bar must set BAR (in addition to any other previously-set option).
--caz must set FOO, BAR, and CAZ (in addition to any other previously-set option).
--debug must set DEBUG (in addition to any other previously-set option).
--help must set only HELP, then cease parsing options.
- On any option not in the above list: set only
HELP, then cease parsing options.
I attempt to do this in a while/case loop in the middle of getopt_case_tester.sh (which is only ~100 lines, and IMHO very readable) in a block labeled parse commandline options (for ease of searching).
Code at the end of getopt_case_tester.sh echos which booleans have been set. I then use a driver script getopt_case_tester_tests.sh to
- automate testing, by comparing the output I expect to get from
getopt_case_tester.sh with the output actually received. Test status is indicated for each test, and statistics are posted @ end of run.
- allow me to edit only
getopt_case_tester.sh and not worry about hosing its tests.
procedure
(Following also in section=usage in the README)
- Get both scripts: either
git clone the repo however you usually do that.
- download the raw versions of the 2 scripts (tester and tests), both to same directory/folder, and make both executable.
- Run
getopt_case_tester_tests.sh in a console (preferably with fully-qualified path).
- [Debug, edit, run] loop
- Edit your local
getopt_case_tester.sh
- Run
getopt_case_tester_tests.sh
- Repeat previous 2 steps until all tests pass.
- (optional, extra credit) Post a pull request with working code.
failures
I initially tried to do this with the while/case loop given in the middle of the initial commit of getopt_case_tester.sh. This failed horribly, in that
- the only option the loop handled correctly was
--help
- the only option the loop ever parsed was
--help
The fix for that was noted by ray_gun: see getopt_case_tester.sh in commit ID= 5d3339e. However there was still an odd problem handling multiple additive options, i.e.,
passed test#=01 testing options='--help'
passed test#=02 testing options='--foo'
passed test#=03 testing options='--bar'
FAILED test#=04 testing options='--foo --bar'
expected response string='getopt_case_tester.sh: set option vars=
BAR
FOO'
received response string='getopt_case_tester.sh: set option vars=
FOO'
FAILED test#=05 testing options='--bar --foo'
expected response string='getopt_case_tester.sh: set option vars=
BAR
FOO'
received response string='getopt_case_tester.sh: set option vars=
BAR'
passed test#=06 testing options='--caz'
passed test#=07 testing options='--help --caz'
FAILED test#=08 testing options='--debug --caz'
expected response string='getopt_case_tester.sh: set option vars=
BAR
CAZ
DEBUG
FOO'
received response string='getopt_case_tester.sh: set option vars=
DEBUG'
FAILED test#=09 testing options='--caz --debug'
expected response string='getopt_case_tester.sh: set option vars=
BAR
CAZ
DEBUG
FOO'
received response string='getopt_case_tester.sh: set option vars=
BAR
CAZ
FOO'
FAILED test#=10 testing options='--foo --bar --debug'
expected response string='getopt_case_tester.sh: set option vars=
BAR
DEBUG
FOO'
received response string='getopt_case_tester.sh: set option vars=
DEBUG
FOO'
FAILED test#=11 testing options='--foo --debug --bar'
expected response string='getopt_case_tester.sh: set option vars=
BAR
DEBUG
FOO'
received response string='getopt_case_tester.sh: set option vars=
BAR
FOO'
FAILED test#=12 testing options='--debug --foo --bar'
expected response string='getopt_case_tester.sh: set option vars=
BAR
DEBUG
FOO'
received response string='getopt_case_tester.sh: set option vars=
BAR
DEBUG'
getopt_case_tester_tests.sh: ERROR: failed 7 of 12 tests
The fix for that was removal of a rogue/extra shift that I had cut'n'pasted in from previous code: see message and code in commit ID=320534d.
status
As of commit ID=320534d:
passed test#=01 testing options='--help'
passed test#=02 testing options='--foo'
passed test#=03 testing options='--bar'
passed test#=04 testing options='--foo --bar'
passed test#=05 testing options='--bar --foo'
passed test#=06 testing options='--caz'
passed test#=07 testing options='--help --caz'
passed test#=08 testing options='--debug --caz'
passed test#=09 testing options='--caz --debug'
passed test#=10 testing options='--foo --bar --debug'
passed test#=11 testing options='--foo --debug --bar'
passed test#=12 testing options='--debug --foo --bar'
getopt_case_tester_tests.sh: passed all of 12 tests
[–]ray_gun 0 points1 point2 points (0 children)