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?

ramkrishna
sumber

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.

jimmij
sumber
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