Bash arguments: Difference between revisions
From wikinotes
Line 80: | Line 80: | ||
Say for example you wanted to accept the following calls (similar to ls). | Say for example you wanted to accept the following calls (similar to ls). | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
foo -abc | foo -abc # same as `foo -a -b -c` | ||
foo -a -bc | foo -a -bc # same as `foo -a -b -c` | ||
foo -a --other # same as `foo -a -b -c --other` | foo -a --other # same as `foo -a -b -c --other` | ||
foo -abc -depth 2 # same as `foo -a -b -c -depth 2` | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
# now use your param case statement | # now use your param case statement | ||
case $1 in | case $1 in | ||
-h|--help) | |||
echo "help me obi-wan kenobi" | echo "help me obi-wan kenobi" | ||
return 0 | |||
;; | ;; | ||
--other) | |||
echo "other" | echo "other" | ||
;; | ;; | ||
esac | -*) | ||
param="$1" | |||
if echo "$param" | grep -E '^-[abc]+$' 2>&1 > /dev/null ; then | |||
for ((i=2; i<=${#param}; i++)); do # each letter, after '-' | |||
case ${param[$i]} in | |||
a) | |||
echo "a received" | |||
;; | |||
b) | |||
echo "b received" | |||
;; | |||
c) | |||
echo "c received" | |||
;; | |||
esac | |||
done | |||
shift | |||
elif [[ "$1" == "-depth" ]] ; then | |||
local DEPTH=$1 | |||
shift 2 | |||
fi | |||
;; | |||
esac | esac | ||
</syntaxhighlight> | </syntaxhighlight> |
Revision as of 19:23, 18 July 2021
Arguments are handled the same way for functions and modules.
Argument Variables
$1 # first argument
$2 # second argument
# ... etc.
$# # number of arguments
$@ # array of all arguments
${@[$#]} # last argument
Parsing Arguments
Regular Params
parsing arguments in this way, it does not matter the order that parameters are passed in, or if they have are keyword arguments with a value.
# PARSE ALL ARGUMENTS while [ $# -gt 0 ] ; do case $1 in -f|--file) filepath=$2 shift 2 # jump forwards twice (once for '--file', once for 'filepath') ;; -d|--debug) debug=1 shift ;; *) echo "default behaviour" ;; esac doneHere is another variation
function parse_args() { args=($@) for ((i=0; i <= ${#args[@]}; i++)) do case "${args[$i]}" in -h|--help) print_help exit 0 ;; -L) LOCAL_PORTS+=( ${args[$i+1]} ) ((i++)) ;; -R) REMOTE_PORTS+=( ${args[$i+1]} ) ((i++)) ;; -t|--test) TEST=1 ;; *) SSH_PARAMS+=" ${args[$i]}" ;; esac done }Combined Single Letter Params
Bash doesn't support regex, so we're limited to manually repeating character ranges.
Say for example you wanted to accept the following calls (similar to ls).
foo -abc # same as `foo -a -b -c` foo -a -bc # same as `foo -a -b -c` foo -a --other # same as `foo -a -b -c --other` foo -abc -depth 2 # same as `foo -a -b -c -depth 2`# now use your param case statement case $1 in -h|--help) echo "help me obi-wan kenobi" return 0 ;; --other) echo "other" ;; -*) param="$1" if echo "$param" | grep -E '^-[abc]+$' 2>&1 > /dev/null ; then for ((i=2; i<=${#param}; i++)); do # each letter, after '-' case ${param[$i]} in a) echo "a received" ;; b) echo "b received" ;; c) echo "c received" ;; esac done shift elif [[ "$1" == "-depth" ]] ; then local DEPTH=$1 shift 2 fi ;; esac
Counting Arguments
if [ $# -gt 2 ]; then echo "if there are more than 2 arguments" fi# see also -eq # equal -ne # not equal -gt # greater than -ge # greater or equal -lt # less than -le # less or equal
Iterating Arguments
for arg in "${args[@]}"; do echo $arg done for (( i=1; i<=(($#-1)); i++ )) ; do echo ${@[$i]}; done