Fornisci due argomenti a un'opzione usando getopts


10

Nel codice seguente quando do l'opzione rquindi getoptsrichiede uno degli argomenti:

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

Ma devo passare due argomenti dopo l' -ropzione, anziché uno. C'è un modo semplice per farlo?

Risposte:


20

Non è possibile passare due argomenti con l'opzione singola usando getopts.

Raccomando le seguenti alternative:

  1. Metti le virgolette intorno a più argomenti

    In questo caso getopts li tratterà come un argomento, ma sarai in grado di dividerlo in seguito. È anche possibile inserire tutti gli argomenti nell'array contemporaneamente:

    #!/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"

    L'esempio della corsa:

    ./script -r "123 456 789"

    E uscita:

    Run Numbers - argument = 123 456 789 
    Number of arguments: 3
    Arguments are: 123, 456, 789
  2. Usa una virgola (o altro carattere preferito) come delimitatore

    ./script -r 123,456,789

    e ti basta sostituire IFS=" "con IFS=,nel codice sopra. Quello ha il vantaggio di consentire elementi vuoti. Come sottolineato nella sezione commenti, questa soluzione è scelta da alcuni programmi comuni, ad es lsblk -o NAME,FSTYPE,SIZE.

  3. Consenti più -ropzioni

    Molteplici -r, ma ognuno accetta solo un argomento:

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

    Quindi gli argomenti verrebbero aggiunti all'array uno per uno

    array+=("$OPTARG")

    Quello ha il vantaggio di non avere limitazioni su quali caratteri possono contenere gli elementi. Questo è usato anche da alcuni strumenti linux standard, ad es awk -v var1=x -v var2=y.


3
L'idea del delimitatore di virgola è buona, in quanto viene utilizzata da vari comandi standard, in particolare mount.
PM 2Ring

Possibile, si può ancora trasformare questo modulo "delimitato" in array con array=(${OPTARG//,/ }). Un'altra possibilità è quella di utilizzare solo più volte -r argogni volta l'aggiunta di elementi a un array array+=($OPTARG).
Jimmij,

Ancora più semplice:IFS=',' array=($OPTARG)
PM 2Ring

Esempi: pgrepusa la virgola ps -s 123,456 ...:, grep usa la ripetizione dell'opzione: grep -e pattern1 -e pattern2 ...( -eè facoltativo quando viene usato un solo motivo).
Volker Siegel,

2
non si desidera che l'utente faccia più lavoro, ad esempio inserendo virgolette nell'elenco, solo a causa di una limitazione nella lingua / libreria che si sta utilizzando. Tuttavia l'uso di ,sembra ragionevole, persino preferibile all'uso di uno spazio.
ctrl-alt-delor,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.