Empty $OPTARG with getopts "b:" and ''./script -b foo'' - bash

I'm trying to create a bash file that will accept command line parameters, but my OPTARG isn't producing any result, which it appears is necessary to get this to work?
Here is what I have:
#!/bin/bash
while getopts ":b" opt; do
case $opt in
b)
echo "result is: $OPTARG";;
\?)
echo "Invalid option: -$OPTARG" >&2;;
esac
done
When I run that with: file.sh -b TEST, this is the result I get: result is:
Any ideas what is going on here?

You're missing a colon after b (not needed before b).
Use this script:
#!/bin/bash
while getopts "b:" opt; do
case $opt in
b)
echo "result is: $OPTARG";;
*)
echo "Invalid option: -$OPTARG" >&2;;
esac
done

Related

Bash script not getting input variable

I have a simple bash script, see below
#!/bin/bash
while getopts "t" opt; do
case $OPT in
t) JWT_TOKEN="$OPTARG"
;;
\?) echo "Invalid option -$OPTARG" >&2
;;
esac
done
echo "Token value is $JWT_TOKEN"
A simple test call is
my-script.sh -t 'test'
However this creates the following output
sedavidw#MacbookPro~$ sh my-script.sh -t 'test'
Token value is
sedavidw#MacbookPro~$
UPDATE
Was able to fix my script by changing it to
#!/bin/bash
while getopts "t:" opt; do
case "${opt}" in
t) JWT_TOKEN="$OPTARG"
;;
\?) echo "Invalid option -$OPTARG" >&2
;;
esac
done
echo "Token value is $JWT_TOKEN"
From the comments it looks like the t: change was helpful for the argument. But still not clear on the syntax change for the "${opt}" part, and would like some clarity there

getopts not iterating on shell script

I'm experiencing an issue with a getopts on a bash script. In particular the code below seems not to work with more than 1 parameter.
If I do:
./script.sh - t template-name -m terminal-name
only template variable is populated while if i do
./script.sh - m terminal-name -t template-name
only terminal is pupulated
while getopts ":m:t:r:" optname;
do
case "${optname}" in
"m")
terminal = $OPTARG
;;
"t")
echo "Using template: $OPTARG"
template = "$(cat $OPTARG)"
;;
"r")
reboot="yes"
tput setaf 1; echo "TERMINAL WILL BE REBOOTED WHEN DONE!!"
;;
"?")
echo "Unknown option $OPTARG"
;;
":")
echo "No argument value for option $OPTARG"
;;
*)
# Should not occur
echo "Unknown error while processing options"
;;
esac
done
shift $((OPTIND-1))
I believe that if you are using getopts in a while you do not need the shift.

How to extract a particular pattern passed in command line argument in shell script

Like i am passing this argument to command line
trace.sh -f abc -t 20
i want to extrace (-t 20) in a variable. how to do that?
Thanks
Very basic example (not fully error prone)
err() { echo "$#" >&2; return 1; }
declare -A options
options=([f]="abc" [t]="20") #the defaults
while getopts ":f:t:" opt
do
case "$opt" in
f) options[$opt]="$OPTARG" ;;
t) options[$opt]="$OPTARG" ;;
\?) err "Invalid option -$OPTARG" || exit 1 ;;
esac
done
echo "t: ${options[t]}"
echo "f: ${options[f]}"

getopts when first option is a path in bash

I'm having an issue with getopts in a bash script. Basically my script would have to be called with something like:
./myScript /path/to/a/folder -a -b
What I have at the top of my code is this:
while getopts ":ab" opt; do
case $opt in
a)
variable=a
;;
b)
variable=b
;;
\?)
echo "invalid option -$OPTARG"
exit 0
esac
done
echo "$variable was chosen"
Now, this works as long as I call my script without /path/to/a/folder… How can I make it to work with it instead?
Thanks a lot
If you MUST put a path before the arguments, use a shift command to pop the first positional argument off, and leave the rest for getopts.
# Call as ./myScript /path/to/a/folder -a -b
path_argument="$1"
shift # Shifts away one argument by default
while getopts ":ab" opt; do
case $opt in
a)
variable=a
;;
b)
variable=b
;;
\?)
echo "invalid option -$OPTARG"
exit 0
esac
done
echo "$variable was chosen, path argument was $path_argument"
The more-standard answer, as Etan mentioned, is to put the non-option arguments AFTER the options. Prefer this style, as it makes your script more consistent with built-in POSIX option parsing.
# Call as ./myScript -a -b /path/to/a/folder
while getopts ":ab" opt; do
case $opt in
a)
variable=a
;;
b)
variable=b
;;
\?)
echo "invalid option -$OPTARG"
exit 0
esac
done
shift $((OPTIND - 1)) # shifts away every option argument,
# leaving your path as $1, and every
# positional argument as $#
path_argument="$1"
echo "$variable was chosen, path argument was $path_argument"

Avoid options to be taken as argument automatically

I'd like to do some error checking for a bash script I am writing. In particular, I wish to ensure the following option not to be considered as the argument of an option (intentionally) left empty.
Let's say the following snippet
while getopts “hhelpc1:2:” OPTION
do
case "$OPTION" in
h|help)
usage
exit 1
;;
1)
var1=${OPTARG}
;;
2)
var2=${OPTARG}
;;
c)
test1
;;
esac
done
Assuming my script is called test.sh
By doing something like
./test.sh -1 -2 dddd -c
In the above circumstance test1 output an error message that -2 option is empty. On the opposite, I'd like to raise a warning for -1 being empty, whereas at present -2 will be taken as the argument for -1.
Any help?
Thanks
Andrea
getopts:
only handles short option names, so you cannot put "help" in your option string -- that means you're looking for "-h", "-e", "-l", "-p"
cannot look for missing arguments the way you're hoping. You'll have to examine $OPTARG to check if it looks like one of your options.
Add a leading : to the opt string to handle getopts errors yourself.
Here's a reworking of your code and I'm sure there are plenty of cases I'm not catching
#!/bin/bash
usage () { echo usage ...; }
test1 () { echo test1; }
shopt -s extglob
while getopts ":hc1:2:" opt
do
case $opt in
h)
usage
exit 1
;;
1)
case $OPTARG in
-[hc2]*)
echo "error: required argument missing for -1"
usage
exit 1
;;
*) var1=$OPTARG
;;
esac
;;
2)
case $OPTARG in
-[hc1]*)
echo "error: required argument missing for -2"
usage
exit 1
;;
*) var2=$OPTARG
;;
esac
;;
c)
test1
;;
:)
echo "error: required argument missing for -$OPTARG"
usage
exit 1
;;
\?)
# unknown argument, handle accordingly
;;
esac
done
shift $((OPTIND - 1))
echo "var1=$var1"
echo "var2=$var2"
echo "rest=$*"
Update 2014-01-23
Here's one technique:
do_test1=false
while getopts ...
case $opt in
...
c) do_test1=true ;;
...
esac
done
shift $((OPTIND - 1))
# execute function "test1" if "-c" was given:
$do_test1 && test1

Resources