I am trying to allow strings that have whitespace in them to be counted as whole strings, rather than being parsed. This is what I would like to have happen:
$ ksh program.ksh "what up"
File 'what up' not found.
And this is what I am getting:
$ ksh program.ksh "what up"
File 'what' not found.
File 'up' not found.
This is the code I’ve tried to make work:
wflag=false
cflag=false
while getopts "cw" opt; do
case "$opt" in
c)
cflag=true
;;
w)
wflag=true
;;
/?)
;;
esac
done
The problem lies when 1) I try something above like ksh program.ksh "what up", and 2) when I try something like ksh program.ksh "-w -c". The second one is most confusing, as when I print out wflag and cflag they are both true. Shouldn’t "-w -c" be treated as a string here? It seems as though the kernel (is it the kernel doing the work here?) is parsing this, although that is exactly what I don’t want; I want it to be treated as a string with whitespace. I have read through WordSplitting and ((the article on Arguments, wouldn’t let me post it though)), and think I understand it. Clearly I must be missing something, or not really understanding it after all 😛
My instinct tells me there is something happening with getopts that automatically gets rid of any whitespace. I have tried $(opt) instead of "$opt", as well as with curly braces and/or single quotes (I’m pretty sure single quotes is not what would work though). Alas, no cigar.
Any help would be greatly appreciated, and thank you for reading through this wall of text.
The last item in your
casestatement should have a backslash instead of a slash. Let’s make a couple of other changes for the sake of diagnostics so you can see what’s happening.Now let’s call it several ways:
Fine.
Also fine.
Still fine, but our answer is foreshadowed.
Now we’re getting somewhere. The Korn shell
manpage says:As you can see from the example before this last one, you can run the options together as in
-cw. When you pass an option like'-c -w',getoptssees it as-c-space--and-w. So, in addition to two invalid options (--and-space) it sees both-cand-wand that’s why both flags are getting set. Without the leading colon (which is the way the original script is posted in the question), you should be getting error messages like these:If you look closely, you’ll notice the telltale space and extra dash.
It’s unfortunate that the
manpage doesn’t discuss the ability ofgetoptsto process arguments passed separately or bunched together.I’m not sure if I understand what or if there’s a problem with your
ksh program.ksh "what up"example.Try my modified script with these options and arguments to see how the rest of it works.
That last one is tricky. When an argument that doesn’t begin with a dash is found and the preceding option doesn’t take an argument, the
getoptsstops processing and the rest of the arguments are left in place. You can useshift $(($OPTIND - 1))after thewhileloop and then you’ll be able to access the remaining positional parameters in the usual way.Unfortunately, the shell builtin
getoptsdoesn’t handle long options like--version. The external utilitygetoptdoes, but there can be some issues that have to be dealt with when it is used.