Based on your example script invocation:
ksh -x test.sh -c -e file1 file2
- the '-c' option does not have an argument
- the '-e' option does have an argument (ie, 'file1')
If this is the case, try removing the colon (:
) after the letter 'c' in your getopts
option string, eg:
while getopts ":ce:" opt; do
If this fixes your issue ... keep reading for more details ...
When a colon (:
) follows a letter in the getopts
option string, this signifies that the option has an argument, which in turn means OPTARG will be set to the next item read from the command line.
When there is no colon following a letter in the getopts
option string, this signifies the option does not have an argument, which in turn means OPTARG will be unset.
We can see this behavior with the following sample scripts:
For this first script we're expecting an argument after each of our options (c,e) - notice the colon (:
) after each letter (c,e) in the getopts
option string:
$ cat test1.sh
#!/bin/ksh
while getopts :c:e: opt
do
case $opt in
c) echo "c: OPTARG='${OPTARG:-undefined}'" ;;
e) echo "e: OPTARG='${OPTARG:-undefined}'" ;;
*) echo "invalid flag" ;;
esac
done
A couple test runs:
$ test1.sh -c -e file1
c: OPTARG='-e'
- because our 'c' option/flag is followed by a colon (c:), the '-e' is treated as the argument to the '-c' option; since the '-e' is consumed on this pass through
getopts
...
- there are no more option flags to process and therefore the
getopts
case for the 'e' option is never accessed
$ test1.sh -c filex -e file1
c: OPTARG='filex'
e: OPTARG='file1'
- because we've provided an argument for both of our options/flags (c,e), we see that both
getopts
cases are processed as desired
Now, if we don't want the '-c' option to have an argument, then we need to remove the colon (:
) that follows the letter 'c' in our getopts
option string:
$ cat test2.sh
#!/bin/ksh
while getopts :ce: opt
do
case $opt in
c) echo "c: OPTARG='${OPTARG:-undefined}'" ;;
e) echo "e: OPTARG='${OPTARG:-undefined}'" ;;
*) echo "invalid flag" ;;
esac
done
$ test2.sh -c -e file1
c: OPTARG='undefined'
e: OPTARG='file1'
- because our 'c' option/flag is not followed by a colon,
getopts
does not read any more items from the command line, which means ...
- for the next pass through
getopts
the '-e' option/flag is processed and OPTARG is set to 'file1'