name: "Builtins: getopts" cases: - name: "Basic getopts" stdin: | func() { echo "Beginning of args" while getopts "ab:" option "$@"; do case ${option} in a) echo "Option a; OPTARG=${OPTARG}";; b) echo "Option b; OPTARG=${OPTARG}";; *) echo "Unknown option: ${option}";; esac echo "OPTIND is now ${OPTIND}" echo "OPTERR is now ${OPTERR}" echo "----------------" done echo "Result: $?" echo "option: ${option}" echo "End of args" } func -a -b my_b_arg echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" - name: "getopts: no args" stdin: | getopts "a:b:" myvar echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" - name: "getopts: toplevel positional parameters" stdin: | set -- -a value getopts "a:b:" myvar echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" - name: "getopts: function positional parameters" stdin: | my_function() { getopts "a:b:" myvar echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" } my_function -b value - name: "getopts: function script parameters" test_files: - path: script.sh contents: | getopts "a:b:" myvar echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" stdin: | source ./script.sh -a value - name: "getopts: no options given" stdin: | while getopts "a:b:" myvar notoption; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" echo "----------------" done echo "Done; result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" - name: "getopts: options and non-options" stdin: | while getopts "ab:" myvar -a -b value notoption; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" echo "----------------" done echo "Done; result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" - name: "getopts: --" stdin: | while getopts "ab:" myvar -a -b value -- -c notoption; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" echo "----------------" done echo "Done; result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" - name: "getopts: -- as first arg" stdin: | while getopts "ab:" myvar -- -a; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" echo "----------------" done echo "Done; result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" - name: "getopts: invalid option when optstr starts with colon" stdin: | getopts ":a:" myvar -b value echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" - name: "getopts: invalid option when optstr does not start with colon" ignore_stderr: true stdin: | getopts "a:" myvar -b value echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" - name: "getopts: multiple options in one token" stdin: | while getopts "a:bcdefg" myvar -fedcba something -g; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" echo "----------------" done echo "Done; result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" - name: "getopts: short option and value in single arg" stdin: | getopts "p:" myvar -p- echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" while getopts "abep:" myvar -abpsomething-else; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" echo "OPTERR: ${OPTERR}" echo "-----------------" done - name: "getopts: OPTERR=0 suppresses error for unknown option" stdin: | OPTERR=0 getopts "a:" myvar -x 2>/dev/null echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: OPTERR=1 shows error for unknown option" ignore_stderr: true stdin: | OPTERR=1 getopts "a:" myvar -x echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: OPTERR nonzero shows error" ignore_stderr: true stdin: | OPTERR=42 getopts "a:" myvar -x echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" - name: "getopts: missing required argument without leading colon" ignore_stderr: true stdin: | getopts "a:" myvar -a echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: missing required argument with leading colon" stdin: | getopts ":a:" myvar -a echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" - name: "getopts: missing required argument with OPTERR=0" stdin: | OPTERR=0 getopts "a:" myvar -a 2>/dev/null echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: combined unknown and missing arg errors" ignore_stderr: true stdin: | func() { while getopts "a:b:" opt "$@"; do case "$opt" in a) echo "a=$OPTARG" ;; b) echo "b=$OPTARG" ;; \?) echo "unknown" ;; :) echo "missing arg for $OPTARG" ;; esac done } func -a foo -x -b echo "Done: $?" - name: "getopts: bare dash as argument" stdin: | getopts "ab:" myvar - echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: leading colon with dash-colon option" stdin: | getopts ":a:" myvar -: echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" - name: "getopts: unknown option in middle of combined flags" ignore_stderr: true stdin: | while getopts "ac" myvar -axc; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" echo "----------------" done echo "Done; result: $?" echo "myvar: ${myvar}" - name: "getopts: missing arg in combined flags" ignore_stderr: true stdin: | while getopts "a:b" myvar -ba; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" echo "----------------" done echo "Final: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: combined flags with arg-taking option consumes next arg" stdin: | while getopts "a:b" myvar -ba nextarg; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" echo "----------------" done echo "Done; result: $?" echo "myvar: ${myvar}" echo "OPTIND: ${OPTIND}" - name: "getopts: OPTIND reset between calls" stdin: | while getopts "a:b" myvar -b -a foo; do echo "myvar: ${myvar}; OPTARG: ${OPTARG-UNSET}; OPTIND: ${OPTIND}" done echo "--- reset ---" OPTIND=1 while getopts "a:b" myvar -b -a bar; do echo "myvar: ${myvar}; OPTARG: ${OPTARG-UNSET}; OPTIND: ${OPTIND}" done - name: "getopts: empty optstring" ignore_stderr: true stdin: | getopts "" myvar -a echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: OPTIND=0" stdin: | OPTIND=0 getopts "a:" myvar -a value echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" - name: "getopts: negative OPTIND treated as reset" stdin: | OPTIND=-1 getopts "a:" myvar -a value echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" - name: "getopts: bare dash among other args" stdin: | while getopts "ab" myvar -a - -b; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" echo "----------------" done echo "Done; result: $?" echo "myvar: ${myvar}" echo "OPTIND: ${OPTIND}" - name: "getopts: OPTIND past end of args" stdin: | OPTIND=100 getopts "a:b:" myvar -a value echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: missing arg with leading colon in combined flags" stdin: | while getopts ":a:b" myvar -ba; do echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" echo "----------------" done echo "Done; result: $?" - name: "getopts: non-numeric OPTIND treated as reset" stdin: | OPTIND=abc getopts "a:" myvar -a value echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" - name: "getopts: option value is empty string" stdin: | getopts "a:" myvar -a "" echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: '${OPTARG}'" echo "OPTIND: ${OPTIND}" - name: "getopts: option value looks like another option" stdin: | getopts "a:b" myvar -a -b echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG}" echo "OPTIND: ${OPTIND}" - name: "getopts: OPTIND=0 resets mid-parse of combined options" stdin: | getopts "abc" myvar -abc echo "first: ${myvar}" OPTIND=0 getopts "abc" myvar -abc echo "after reset: ${myvar}" - name: "getopts: OPTERR non-numeric treated as enabled" ignore_stderr: true stdin: | OPTERR=abc getopts "a:" myvar -x echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: invalid variable name rejected" ignore_stderr: true stdin: | getopts "a" "123abc" -a echo "Result: $?" - name: "getopts: duplicate option char in optstring uses first definition" stdin: | getopts "aa:" myvar -a val echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: optstring is only a colon" ignore_stderr: true stdin: | getopts ":" myvar -a echo "Result: $?" echo "myvar: ${myvar}" echo "OPTARG: ${OPTARG-UNSET}" echo "OPTIND: ${OPTIND}" - name: "getopts: empty string argument is not an option" stdin: | getopts "a" myvar "" echo "Result: $?" echo "myvar: ${myvar}" echo "OPTIND: ${OPTIND}" - name: "getopts writes through nameref" known_failure: true stdin: | declare -n ref=result getopts "a:b" ref -a value echo "Result: $?" echo "result: ${result}" echo "ref: ${ref}" echo "OPTARG: ${OPTARG}" - name: "getopts writes through subscripted nameref" known_failure: true stdin: | arr=(x x x) declare -n ref='arr[1]' getopts "a:b" ref -a value echo "Result: $?" echo "arr[1]: ${arr[1]}" echo "ref: ${ref}"