Search code examples
bashshellgetopts

Ways to provide list of parameters to options in shell scripts?


Basically I am making a script where I would like to give a list of parameters to some option, say -l, eg:

usr@domain:$./somescript -l hi bye cry nigh

The list specified to -l would be then stored into a specific array and iterated over.

So far, I have been using these lines from Arch linux's mkinitcpio script to do so. This allows one to specify a comma-separated list to an option:

_optaddhooks()

while :; do
    case $1 in
        -A|--add|--addhooks)
            shift
            IFS=, read -r -a add <<< "$1"
            _optaddhooks+=("${add[@]}")
            unset add
            ;;

What are some other methods to do this, particularly when other options/parameters will be used? Can the list provided to an option be space separated? Or is specifying a list by "," (or some other character") easier to manage?


Solution

  • UPDATE: OP is looking for a non-getopts solution; adding a -l option to the current code:

    NOTE: OP has shown the command line flag as -l so not sure what the -A|-add|--addhooks) relates to ... ???

    unset _optaddhooks
    
    while :; do
        case "${1}" in
            -A|--add|--addhooks)
                shift
                ....
                ;;
    
            -a) shift
                vara="${1}"
                ;;
            -l) shift
                _optaddhooks=( ${1} )
                ;;
            -z) shift
                varz="${1}"
                ;;
            ....
        esac
    done
    

    OP would still use the same command line as in the earlier answer (below):

    $ ./somescript -a this_is_a -l 'hi bye cry nigh' -z 123456   
    

    If you're willing to wrap the -l args in quotes you could then pass the args as a single parameter and then have bash parse this parameter however you wish.

    One idea to load the -l args into an array named _optaddhooks[]:

    $ cat somescript
    #!/usr/bin/bash
    
    while getopts :a:l:z: opt
    do
        case ${opt} in
            a)   vara="${OPTARG}"           ;;
            l)   _optaddhooks=( ${OPTARG} ) ;;
            z)   varz="${OPTARG}"           ;;
            *)   echo "Sorry, don't understand the option '${opt}'" ;;
        esac
    done
    
    typeset -p vara _optaddhooks varz
    

    A sample run:

    $ ./somescript -a this_is_a -l 'hi bye cry nigh' -z 123456
    declare -- vara="this_is_a"
    declare -a _optaddhooks=([0]="hi" [1]="bye" [2]="cry" [3]="nigh")
    declare -- varz="123456"
    

    While this was a simple example, it should be easy enough to modify the code (l section of the case statement) as needed.