Search code examples
bashgetopts

Bash script using getopts to store strings as an array


I am working on a Bash script that needs to take zero to multiple strings as an input but I am unsure how to do this because of the lack of a flag before the list.

The script usage:

script [ list ] [ -t <secs> ] [ -n <count> ]

The list takes zero, one, or multiple strings as input. When a space is encountered, that acts as the break between the strings in a case of two or more. These strings will eventually be input for a grep command, so my idea is to save them in an array of some kind. I currently have the -t and -n working correctly. I have tried looking up examples but have been unable to find anything that is similar to what I want to do. My other concern is how to ignore string input after a flag is set so no other strings are accepted.

My current script:

while getopts :t:n: arg; do
  case ${arg} in
    t)
      seconds=${OPTARG}
      if ! [[ $seconds =~ ^[1-9][0-9]*$ ]] ; then
        exit
      fi
      ;;
    n)
      count=${OPTARG}
      if ! [[ $count =~ ^[1-9][0-9]*$ ]] ; then
        exit
      fi
      ;;
    :)
      echo "$0: Must supply an argument to -$OPTARG" >&2
      exit
      ;;
    ?)
      echo "Invalid option: -${OPTARG}"
      exit
      ;;
  esac
done

Edit: This is for a homework assignment and am unsure if the order of arguments can change

Edit 2: Options can be in any order


Solution

  • Would you please try the following:

    #!/bin/bash
    
    # parse the arguments before getopts
    for i in "$@"; do
        if [[ $i = "-"* ]]; then
            break
        else                # append the arguments to "list" as long as it does not start with "-"
            list+=("$1")
            shift
        fi
    done
    
    while getopts :t:n: arg; do
        : your "case" code here
    done
    
    # see if the variables are properly assigned
    echo "seconds=$seconds" "count=$count"
    echo "list=${list[@]}"