tl;dr summary: In Bash, what is the best way to handle multiple command line arguments with varying positions depending on user input?
I have a script with multiple case statements to handle multiple arguments. However, the position of each argument may vary depending on user input. I have something like this:
case $1 in
-a)
this lists all package tracking info
;;
-u)
this lists only the most recent update
;;
-d)
this runs -u in a loop of intervals of n (secs, mins, or hours)
;;
...
esac
case $2 in
-f)
this parses $file (default or user-defined)
;;
...
esac
The tricky part here is that when the user passes the argument -d
, they have the additional option of specifying a time interval for daemon()
to run it's loop, such as -d 2h
. I also want to give the user the ability to specify a file to parse (the -f
flag). When the user specifies -d -f
, there's no problem, but when they specify a time and a file, -d 2h -f file.txt
, then $2
= 2h
and$3
= -f
causing -f
to get interpreted as something else (a package tracking number) later on in the script.
So, I tried to use a conditional in between case statements 1 and 2 to change the $2
in the 2nd case statement. Something like:
if [[ "$2" =~ ^.[h,m,s] ]];
then
last_flag="/$3"
else
last_flag="/$2"
fi
case $last_flag in
-f)
check_flag
;;
esac
But, this doesn't appear to work. when I enter -d 2h -f
at the command line,echo $last_flag
= $3
as expected, but $last_flag
isn't being substituted in the case statement. I don't think the escaped $ is the problem, either (I tried it without that as well).
- What am I doing wrong here?
- Is there a better way to handle multiple input arguments with varying positions in Bash?
I suppose the easiest thing would be to simply change the order of the flags, leaving -d
at the end, so it doesn't matter whether the user specifies a time-interval or not. But, there are other circumstances in which input arguments would be shifted, such as if the user passes -f
but doesn't supply a file name (in which case a default file is chosen). So, either way, I have to confront this problem. I suspect it will require a re-write of the general flow of the script, but perhaps not.