Reputation: 45
I have a code that I wrap with a bash script, and I want to know if a certain flag was given (-b), and if so, to update some variable I have in the script (called "x"). Unfortunately, I need this to be done on the bash script, and the synthax here drives me nuts. A small example of what I did is (without the call to the code I wrap):
#!/bin/bash
x=0
while getopts :b opt; do
case $opt in
b) x=1;;
?) echo "";;
esac
done
echo "x is ${x}"
My problem is with having more than one flag I want to pass to the command line.
I tried to use:
while getopts :b:f:c opt; do
..., but it looks like it fails to work when I do not give the flags in the -b -f ... -c ...
order (I get x is 0
when I expect it to be x is 1
).
Moreover, this does not work when I want to give flags with the --
prefix (--frame
instead of -f
).
What should be the code for this purpose? I tried a few options but I do not manage to figure out what should the synthax exactly.
Thank you in advance.
Upvotes: 0
Views: 1585
Reputation: 29075
Options with argument have a colon after their character in the optstring
. So getopts :b:c:f
means:
-b
option that takes an argument (b:
)-c
option that takes an argument (c:
)-f
option that takes no argument (f
)If you use while getopts :b:f:c opt; do...
in your script and you type:
./script.sh -c -b -f
-b
is considered as the argument of option -c
, not as an option itself.
Considering this part of your question: "it looks like it fails to work when I do not give the flags in the -b -f ... -c ... order", let's assume you want the b
option to have no argument, and the f
and c
options to have one.
If your option has no argument don't put a colon after it in the optstring
parameter; else put the colon after the option character. With your simple example you could try:
#!/bin/bash
x=0
fopt=""
copt=""
while getopts bf:c: opt; do
case "$opt" in
b) x=1;;
f) echo "f option found"; fopt="$OPTARG";;
c) echo "c option found"; copt="$OPTARG";;
?) echo "";;
esac
done
echo "x is ${x}"
echo "fopt is ${fopt}"
echo "copt is ${copt}"
And then:
$ ./script.sh -b -c foo -f bar
c option found
f option found
x is 1
fopt is bar
copt is foo
$ ./script.sh -c foo -f bar
c option found
f option found
x is 0
fopt is bar
copt is foo
$ ./script.sh -c foo -b
c option found
x is 1
fopt is
copt is foo
But be careful: with the last example, if you omit the foo
argument of the -c
option:
./script.sh -c -b
c option found
x is 0
fopt is
copt is -b
See? -b
became the missing argument and has not been considered as an option. Is it the cause of your problem?
Note: If you want to also use long options don't use the bash
getopts
builtin, use thegetopt
utility.
Upvotes: 3