How to use getopts with unix shell functions? - bash

The getopts command doesn't seem to work in a function. Maybe I did something wrong. The code below is what I have now. it is working if I put the whole while loop outside function. I am wondering if there is a way to make getopts work with functions ? I am new to the shell script. Any help would be appreciated :)
getOptions()
{
while getopts :al:f:vd opt; do
case "$opt" in
l) logFile = $OPTARG ;;
f) fileTable = $OPTARG ;;
v) verbose = 1 ;;
d) set -x ;;
a) echo "a";;
\?) echo "Invalid option: -$opt";;
esac
done
shift $(($OPTIND - 1))
}

One reason might be your usage of things like logFile = $OPTARG when you shouldn't have any spaces there (it should read logFile=$OPTARG).
Another reason is the fact that $1, $2, etc. are all referring to the function's arguments, not the shell script's arguments. Since the shell works that way, and getopts uses $1, $2, etc., you're using the function's arguments with getopts, not the script's arguments. In other words, confining your option processing to a shell function is not a good idea.

Related

bash - getopts in switch case

I'm trying to use getopts inside a switch case loop.
if i use only getopts or only the switch case it's work, however when i combine those two the getopts dos not trigger.
i have search a lot but i cat fins any mention for how to combine them, and problem i missing something stupid so for give me ...
here is the code essence.
#!/bin/bash
case $1 in
ver)
echo "vesion"
exit 0
;;
op)
while getopts ":a" opt; do
case $opt in
a)
echo "-a was triggered!" >&2
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
;;
esac
when i do that
# bash -x test.sh op -a
i get
+ case $1 in
+ getopts :a opt
(and without debug i get nothing)
what is that that i missing to combine these two
Thanks :)
You should add a shift instruction at the beginning of your op) choice, before the call to getopts, to eat the op argument itself. Else, the first argument that getopts will analyze is op and it will silently stop (end of options).

Using getopts with a switchless path

I am trying to write a short script, utilizing getopts. I want it to take optional switches, or just run as the default. I have a -d switch to enable debugging, and I'd like every other argument to be a path. The ideal command line looks as such, with paths being optional, and theoretically limitless:
$0 [-d] [/path1[ /path2[ ...]]]
I am currently using getopts as such below:
while getopts ":d" opt; do
case $opt in
d)
DEBUG=true
;;
h)
echo USAGE: $0 \[-d\] \[\/mount\/point\/1 ...\]
exit 0
;;
\?)
echo Incorrect syntax
;;
esac
done
What can I put in the while getopts section, and in the case set, to allow paths to be entered, as many as needed?
You don't need anything in the loop or getopts call for that. getopts stops at the first non-option.
After your loop all your paths will still be in positional arguments available for use.
Also you don't have h in your getopts string so it isn't valid.

bash getopts options for different functions

how can I make this work? I want to use different functions for my command, my problem is how can I pass arguments to the add.sh function? find.sh works fine but the first two commands says no arg for -v / -a option. What am I doing wrong?
while getopts v:a:s opt
do
case "$opt" in
v) ./view.sh;;
a) ./add.sh;;
s) ./find.sh;;
If you want to pass the -v option onto the view.sh script, then do so:
while getopts v:a:s opt
do
case "$opt" in
v) ./view.sh -v "$OPTARG";;
a) ./add.sh -a "$OPTARG";;
s) ./find.sh;;
esac
done
If you want to pass the 'other' arguments to view.sh too, then you have to work a bit harder. You could simply pass all the arguments with ./view.sh "$#";; but being selective is harder.

How to have a positional argument before options in a shell script?

I want to have a shell script that takes a file name as first positional argument followed by options (./test.sh <file> [options]). However, getopts doesn't work when I give a positional argument before options. I have the following code:
while getopts "h" opt; do
case $opt in
h)
echo usage
;;
;;
esac
done
echo $1
./test.sh -h prints usage on the shell, but ./test.sh test -h prints test on the shell. So when I give a positional argument before an option it's not doing anything with the option. It does work when having the positional arguments after the option (change echo $1 to echo $BASH_ARGV and the call to ./test.sh -h test). How can I have the positional argument before the options?
The shell builtin getopts does not support reordering the parameters. If you want parameter reordering, you need to use one of the enhanced getopt variants (e.g. gnu getopt or bsd getopt). Please note that the default bsd getopt does not support long options (e.g. when used on Mac OS X)
Try to replace "h" to h
while getopts h opt; do...
And also you have to add minus in your case
case "$opt" in
-h)...
If you know, that your [file] will always be present, can you just use
filename="$1"
shift
And than parse other arguments

is bash getopts function destructive to the command-line options?

Can you use the bash "getopts" function twice in the same script?
I have a set of options that would mean different things depending on the value of a specific option. Since I can't guarantee that getopts will evaluate that specific option first, I would like to run getopts one time, using only that specific option, then run it a second time using the other options.
Yes, just reset OPTIND afterwards.
#!/bin/bash
set -- -1
while getopts 1 opt; do
case "${opt}" in
1) echo "Worked!";;
*) exit 1;
esac
done
OPTIND=1
set -- -2
while getopts 2 opt; do
case "${opt}" in
2) echo "Worked!";;
*) exit 1;
esac
done
getopts does not modify the original arguments, as opposed to the older getopt standalone executable. You can use the bash built-in getopts over and over without modifying your original input.
See the bash man page for more info.
HTH.
cheers,
Rob

Resources