Bash arguments: Difference between revisions

From wikinotes
Line 94: Line 94:
case_value="${case_value:1}"  # "-[abc]|-[abc][abc]|-[abc][abc][abc]"
case_value="${case_value:1}"  # "-[abc]|-[abc][abc]|-[abc][abc][abc]"


# now use in case statement
# now use your param case statement
case $1 in
case $1 in
     $case_value)
     $case_value)
Line 106: Line 106:
             echo "c received"
             echo "c received"
             ;;
             ;;
    --help)
        echo "help me obi-wan kenobi"
        ;;
  --other)
        echo "other"
        ;;
     esac
     esac
esac
esac

Revision as of 17:58, 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
done

Here 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.

# these are all available single-letter params
# ex: foo -a -b -c
avail_letters="abc"

# accept as many as avail_letters, 
# only in combinations of avail_letters
case_value=$(
    for ((i=1; i<=${#avail_letters}; i++)); do 
        echo -n "|-$(printf "[${avail_letters}]%.0s" {1..$i})" 
    done
)

# strip 1st '|'
case_value="${case_value:1}"  # "-[abc]|-[abc][abc]|-[abc][abc][abc]"

# now use your param case statement
case $1 in
    $case_value)
        case a)
            echo "a received"
            ;;
        case b)
            echo "b received"
            ;;
        case c)
            echo "c received"
            ;;
    --help)
        echo "help me obi-wan kenobi"
        ;;
   --other)
        echo "other"
        ;;
    esac
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