I have a scenario where i would like to assign an option a default value but a user can decide to give it another argument:
Here is an example
check_param() {
for arg in "$@"; do
shift
case "$arg" in
"--force") set -- "$@" "-f" ;;
"--type") set -- "$@" "-t" ;;
"--help") set -- "$@" "-h" ;;
"--"*) echo "Unknown parameter: " $arg; show_help; exit 1 ;;
*) set -- "$@" "$arg"
esac
done
# Standard Variables
force=0
type="daily"
OPTIND=1
while getopts "hft:v" opt
do
case "$opt" in
"f") force=1 ;;
"t") type=${OPTARG} ;;
"h") show_help; exit 0 ;;
"?") show_help; exit 1 ;;
esac
done
shift $(expr $OPTIND - 1) # remove options from positional parameters
From the above example, i would like when the user gives the parameter -t
without any argument to apply the default value which is daily
, and the user can also use parameter -t
with any other argument and that will be checked later in code.
The problem is now the parameter -t
must be given an argument due to the colon, but i kinda need for it to do both, with or without argument.
Thanks in advance for any explanations or links to any article that can help.
So according to a suggestion i got Here is the test result
check_param() {
## Standard Variablen der Parameter
force=0
type="daily.0"
## Break down the options in command lines for easy parsing
## -l is to accept the long options too
args=$(getopt -o hft::v -l force,type::,help -- "$@")
eval set -- "$args"
## Debugging mechanism
echo ${args}
echo "Number of parameters $#"
echo "first parameter $1"
echo "Second parameter $2"
echo "third parameter $3"
while (($#)); do
case "$1" in
-f|--force) force=1; ;;
-t|--type) type="${2:-${type}}"; shift; ;;
-h|--help) show_help; exit 0; ;;
--) shift; break; ;;
*) echo "Unbekannter Parameter"; exit 1; ;;
esac
shift
done
echo ${type}
}
check_param $@
echo ${type}
The output:
sh scriptsh -t patch.0
-t '' -- 'patch.0'
Number of parameters 4
first parameter -t
Second parameter
third parameter --
daily.0
daily.0
It still didn't assign the value patch
to the variable type
Is there a way in bash script to have an option to give an argument but it shouldn't a must?
Yes, there is a way.
getopts
does not supports optional arguments. So... you can:
A common tool is getopt
that should be available on any linux.
args=$(getopt -o hft::v -l force,type::,help -- "$@")
eval set -- "$args"
while (($#)); do
case "$1" in
-f|--force) force=1; ;;
-t|--type) type="${2:-default_value}"; shift; ;;
-h|--help) echo "THis is help"; exit; ;;
--) shift; break; ;;
*) echo "Error parsgin arguments"; exit 1; ;;
esac
shift
done
getopt
handles long arguments and reorders arguments, so you can ./prog file1 -t opt
and ./prog -t opt file1
with same result.