Berikan dua argumen untuk satu opsi menggunakan getopts


10

Dalam kode di bawah ini ketika saya memberikan opsi rmaka getoptsmemerlukan satu argumen:

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

Tapi saya harus memberikan dua argumen setelah -ropsi, bukan satu. Apakah ada cara mudah untuk melakukan ini?

Jawaban:


20

Anda tidak dapat melewati dua argumen dengan opsi tunggal menggunakan getopts.

Saya merekomendasikan alternatif berikut:

  1. Beri tanda kutip di beberapa argumen

    Dalam hal ini, getop akan memperlakukan mereka sebagai satu argumen, tetapi Anda akan dapat membaginya nanti. Anda bahkan dapat menempatkan semua argumen dalam array sekaligus:

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

    Contoh menjalankan:

    ./script -r "123 456 789"

    Dan output:

    Run Numbers - argument = 123 456 789 
    Number of arguments: 3
    Arguments are: 123, 456, 789
  2. Gunakan koma (atau karakter pilihan lainnya) sebagai pembatas

    ./script -r 123,456,789

    dan Anda cukup mengganti IFS=" "dengan IFS=,pada kode di atas. Yang satu memiliki keunggulan memungkinkan elemen kosong. Seperti yang ditunjukkan pada bagian komentar, solusi ini dipilih oleh beberapa program umum misalnya lsblk -o NAME,FSTYPE,SIZE.

  3. Izinkan beberapa -ropsi

    Banyak -r, tetapi masing-masing hanya mengambil satu argumen:

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

    Kemudian argumen akan ditambahkan ke array satu per satu

    array+=("$OPTARG")

    Yang satu memiliki keuntungan karena tidak memiliki batasan pada karakter apa yang mungkin mengandung elemen. Yang ini juga digunakan oleh beberapa alat linux standar misalnya awk -v var1=x -v var2=y.


3
Ide pembatas koma baik, karena digunakan oleh berbagai perintah standar, terutama mount.
PM 2Ring

Kemungkinan, seseorang masih dapat mengubah bentuk "dibatasi" ini menjadi array dengan array=(${OPTARG//,/ }). Namun kemungkinan lain adalah dengan hanya menggunakan -r argopsi beberapa kali setiap kali menambahkan elemen ke array array+=($OPTARG).
jimmij

Lebih mudah:IFS=',' array=($OPTARG)
PM 2Ring

Contoh: pgrepmenggunakan koma ps -s 123,456 ...:, grep menggunakan mengulangi opsi: grep -e pattern1 -e pattern2 ...( -eopsional jika hanya satu pola yang digunakan).
Volker Siegel

2
Anda tidak ingin membuat pengguna melakukan lebih banyak pekerjaan misalnya menaruh tanda kutip di sekitar daftar, hanya karena keterbatasan dalam bahasa / perpustakaan yang Anda gunakan. Namun penggunaan ,tampaknya masuk akal, bahkan lebih disukai daripada penggunaan ruang.
ctrl-alt-delor
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.