Geben Sie mit getopts zwei Argumente für eine Option an

10

Wenn ich im folgenden Code eine Option gebe, sind rdann getoptsein Argument erforderlich:

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

Aber ich muss zwei Argumente nach der -rOption anstelle von einem übergeben. Gibt es eine einfache Möglichkeit, dies zu tun?

ramkrishna
quelle

Antworten:

19

Sie können nicht zwei Argumente mit einer einzigen Option übergeben getopts.

Ich empfehle folgende Alternativen:

  1. Setzen Sie Anführungszeichen um mehrere Argumente

    In diesem Fall werden sie von getopts als ein Argument behandelt, aber Sie können es später aufteilen. Sie können sogar alle Argumente gleichzeitig in das Array einfügen:

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

    Das Beispiel von run:

    ./script -r "123 456 789"

    Und Ausgabe:

    Run Numbers - argument = 123 456 789 
    Number of arguments: 3
    Arguments are: 123, 456, 789
  2. Verwenden Sie ein Komma (oder ein anderes bevorzugtes Zeichen) als Trennzeichen

    ./script -r 123,456,789

    und Sie ersetzen Sie einfach IFS=" "mit IFS=,in dem obigen Code. Dieser hat den Vorteil, leere Elemente zuzulassen. Wie im Kommentarbereich ausgeführt, wird diese Lösung von einigen gängigen Programmen ausgewählt, z lsblk -o NAME,FSTYPE,SIZE.

  3. Erlaube mehrere -rOptionen

    Mehrere -r, aber jeweils nur ein Argument:

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

    Dann würden dem Array nacheinander Argumente hinzugefügt

    array+=("$OPTARG")

    Dieser hat den Vorteil, dass er keine Einschränkungen hinsichtlich der Zeichen hat, die die Elemente enthalten dürfen. Dieser wird auch von einigen Standard-Linux-Tools verwendet, z awk -v var1=x -v var2=y.

jimmij
quelle
3
Die Idee des Komma-Trennzeichens ist gut, da sie insbesondere von verschiedenen Standardbefehlen verwendet wird mount.
PM 2Ring
Möglicherweise kann man diese "abgegrenzte" Form noch in ein Array mit umwandeln array=(${OPTARG//,/ }). Eine weitere Möglichkeit besteht darin, -r argjedes Mal, wenn Sie einem Array ein Element hinzufügen, die Option mehrmals zu verwenden array+=($OPTARG).
Jimmy
Noch einfacher:IFS=',' array=($OPTARG)
PM 2Ring
Beispiele: pgrepverwendet Komma : ps -s 123,456 ..., grep verwendet das Wiederholen der Option: grep -e pattern1 -e pattern2 ...( -eist optional, wenn nur ein Muster verwendet wird).
Volker Siegel
2
Sie möchten den Benutzer nicht dazu bringen, mehr zu arbeiten, z. B. Anführungszeichen um die Liste zu setzen, nur aufgrund einer Einschränkung in der Sprache / Bibliothek, die Sie verwenden. Die Verwendung von ,scheint jedoch vernünftig, sogar der Verwendung eines Raums vorzuziehen.
Strg-Alt-Delor