This shell script takes one -P optional option.
#!/bin/sh
usage() {
echo "Usage: $0 [-P path] URL [URL...]";
exit 0;
}
P='/default_path/'
getopts "P:" OPT && [ "$OPT" == 'P' ] && P=$OPTARG || usage
If there are options, do the followings.
If the option is 'P', then assign the $OPTARG path to the variable P.
If the option is not 'P', print the usage and exit.
The statement above fails the definition when there is no option. When no option is given, getopts "P:" OPT returns false, then usage is called. By idea, I should group the later parts of the expression, as below. But it gives me syntax error.
getopts "P:" OPT && { [ "$OPT" == 'P' ] && P=$OPTARG || usage }
How to group shorthand operators in shell script?
Short answer: Add a semi-colon after usage.
Side note: Actually I opted to use getopt instead of getopts. It is much more versatile and definitely worth learning it.
Side note 2: There are hundreds of threads in SE talking about shell scripts, some with thousands of upvotes. But knowledge is so scattered, while some may focus on usage and lack authentic explanations. Be reminded that
man bashis a very cool resource to begin with (which I did not know I can actuallyman bashas I thoughtbashwas not a command).Explanation, with reference to [`man bash`][2]:
Simple Command:
A command is also a Pipeline:
The first && forms a List:
Although the first
&&behaves like a logical AND, I try to not see it in that way.Let us break to the second part. This is a test expression, which is a Compound Command:
Again, these are three pipelines joining by
&&and||, which explained above:If we need to group these pipelines, we need to use the following format. It must be terminated with a newline or semicolon.
Finally joining the first
Simple Command&&Compound Commands:Cannot think of this header name ...
Using round brackets is syntactically correct. But it cannot set the the variable
P. It is because the assignment will be running in a subshell.