Proporcione dos argumentos para una opción usando getopts


10

En el siguiente código cuando doy la opción, rentonces getoptsrequiere un argumento:

while getopts ":hr::l:" opt; do
    case $opt in
        r ) echo "Run Numbers - argument = $OPTARG " ;;
        l ) echo "Latency range - argument = $OPTARG" ;;
        h ) helptext
            graceful_exit ;;
        * ) usage
            clean_up
            exit 1
    esac
done

Pero necesito pasar dos argumentos después de la -ropción, en lugar de uno. ¿Hay una forma fácil de hacer esto?

Respuestas:


20

No puede pasar dos argumentos con una sola opción usando getopts.

Recomiendo las siguientes alternativas:

  1. Pon comillas alrededor de múltiples argumentos

    En este caso, getopts los tratará como un argumento, pero podrá dividirlo más adelante. Incluso puede poner todos los argumentos en la matriz a la vez:

    #!/bin/bash  
    
    while getopts ":hr:l:" opt; do
        case $opt in
            r ) echo "Run Numbers - argument = $OPTARG "
                set -f # disable glob
                IFS=' ' # split on space characters
                array=($OPTARG) ;; # use the split+glob operator
            l ) echo "Latency range - argument = $OPTARG" ;;
            h ) helptext
                graceful_exit ;;
            * ) usage
                clean_up
                exit 1
        esac
    done
    
    echo "Number of arguments: ${#array[@]}"
    echo -n "Arguments are:"
    for i in "${array[@]}"; do
      echo -n " ${i},"
    done
    printf "\b \n"
    

    El ejemplo de ejecución:

    ./script -r "123 456 789"

    Y salida:

    Run Numbers - argument = 123 456 789 
    Number of arguments: 3
    Arguments are: 123, 456, 789
    
  2. Use una coma (u otro carácter preferido) como delimitador

    ./script -r 123,456,789

    y simplemente reemplazas IFS=" "con IFS=,en el código de arriba. Ese tiene la ventaja de permitir elementos vacíos. Como se señaló en la sección de comentarios, esta solución es elegida por algunos programas comunes, por ejemplo lsblk -o NAME,FSTYPE,SIZE.

  3. Permitir múltiples -ropciones

    Múltiple -r, pero cada uno toma solo un argumento:

    ./script -r 123 -r 456 -r 789

    Entonces los argumentos se agregarían a la matriz uno por uno

    array+=("$OPTARG")

    Ese tiene la ventaja de no tener limitaciones sobre qué caracteres pueden contener los elementos. Este también es utilizado por algunas herramientas estándar de Linux, por ejemplo awk -v var1=x -v var2=y.


3
La idea del delimitador de coma es buena, ya que es utilizada por varios comandos estándar, en particular mount.
— PM 2Ring

Posible, todavía se puede transformar esta forma "delimitada" en una matriz con array=(${OPTARG//,/ }). Otra posibilidad es usar la -r argopción de varias veces cada vez que agrega un elemento a una matriz array+=($OPTARG).
— jimmij

Aún más fácil:IFS=',' array=($OPTARG)
— PM 2Ring

Ejemplos: pgrepusa coma: ps -s 123,456 ...grep usa la opción de repetición: grep -e pattern1 -e pattern2 ...( -ees opcional cuando solo se usa un patrón).
— Volker Siegel

2
no desea que el usuario trabaje más, por ejemplo, ponga comillas alrededor de la lista, solo por una limitación en el idioma / biblioteca que está utilizando. Sin embargo, el uso de ,parece razonable, incluso preferible al uso de un espacio.
— ctrl-alt-delor
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.