Linux Shell Komut Dosyası Seçeneklerini Ayrıştırmak için getopts Nasıl Kullanılır

Yayınlanan: 2022-06-25
Terminal metnini gösteren bir dizüstü bilgisayar ekranı.
fatmawati achmad zaenuri/Shutterstock.com

Linux kabuk komut dosyalarınızın komut satırı seçeneklerini ve argümanları daha zarif bir şekilde işlemesini ister misiniz? Bash getopts yerleşik, komut satırı seçeneklerini incelikle ayrıştırmanıza olanak tanır ve bu da kolaydır. Size nasıl olduğunu gösteriyoruz.

getopts yerleşiğinin tanıtılması

Değerleri bir Bash betiğine geçirmek oldukça basit bir meseledir. Komut satırınızı komut satırından veya başka bir komut dosyasından çağırır ve komut dosyası adının arkasındaki değerler listenizi sağlarsınız. Bu değerlere, ilk değişken için $1 , ikinci değişken için $2 vb. ile başlayarak, komut dosyanızın içinden değişkenler olarak erişilebilir.

Ancak seçenekleri bir komut dosyasına aktarmak istiyorsanız, durum hızla daha karmaşık hale gelir. Seçenekler dediğimizde, ls gibi programların işleyebileceği seçenekler, bayraklar veya anahtarları kastediyoruz. Önlerinde bir " - " işareti bulunur ve genellikle programın işlevselliğinin bazı yönlerini açıp kapatmak için bir gösterge görevi görürler.

Linux'ta Dosyaları ve Dizinleri Listelemek için ls Komutu Nasıl Kullanılır
İLGİLİ Linux'ta Dosyaları ve Dizinleri Listelemek için ls Komutu Nasıl Kullanılır

ls komutu, çoğunlukla çıktısını biçimlendirmeyle ilgili 50'den fazla seçeneğe sahiptir. -X (uzantıya göre sırala) seçeneği, çıktıyı dosya uzantısına göre alfabetik olarak sıralar. -U (sıralanmamış) seçeneği, dizin sırasına göre listelenir.

Seçenekler sadece bu kadardır - isteğe bağlıdırlar. Kullanıcının hangi seçenekleri (varsa) kullanmayı seçeceğini bilmiyorsunuz ve bunları komut satırında hangi sırayla listeleyebileceklerini de bilmiyorsunuz. Bu, seçenekleri ayrıştırmak için gereken kodun karmaşıklığını artırır.

Bazı seçenekleriniz, seçenek argümanı olarak bilinen bir argüman alırsa işler daha da karmaşık hale gelir. Örneğin, ls -w (genişlik) seçeneği, çıktının maksimum görüntüleme genişliğini temsil eden bir sayı tarafından takip edilmesini bekler. Ve elbette, komut dosyanıza yalnızca veri değerleri olan ve hiçbir şekilde seçenek olmayan başka parametreler aktarıyor olabilirsiniz.

Neyse ki getopts bu karmaşıklığı sizin için hallediyor. Yerleşik olduğu için Bash kabuğuna sahip tüm sistemlerde bulunur, dolayısıyla yüklenecek bir şey yoktur.

Not: getopts Getopt değil

getopt adında daha eski bir yardımcı program var. Bu küçük bir yardımcı programdır , yerleşik değildir. Farklı davranışlara sahip birçok farklı getopt sürümü vardır, oysa getops yerleşik POSIX yönergelerini takip eder.

 getopts yazın
 getopt yazın 

getop ve getops arasındaki farkı görmek için type komutunu kullanma

getopt bir yerleşik olmadığı için, boşlukları mantıklı bir şekilde işlemek gibi getopts sağladığı bazı otomatik faydaları paylaşmaz. getopts ile, Bash kabuğu betiğinizi çalıştırıyor ve Bash kabuğu seçenek ayrıştırma yapıyor. Ayrıştırmayı işlemek için harici bir program çağırmanız gerekmez.

Buradaki ödün, getopts çift çizgili, uzun biçimli seçenek adlarını işlememesidir. Böylece -w gibi biçimlendirilmiş ancak ” ---wide-format biçimli” değil gibi biçimlendirilmiş seçenekleri kullanabilirsiniz. Öte yandan, -a , -b ve -c seçeneklerini kabul eden bir komut dosyanız varsa, getopts bunları -abc , -bca veya -bac vb. gibi birleştirmenize izin verir.

Bu makalede getopts tartışıyor ve gösteriyoruz, bu nedenle komut adına son "s"yi eklediğinizden emin olun.

İLGİLİ: Windows Komut Satırında Dosya Yollarında Boşluklardan Kaçış

Hızlı Bir Özet: Parametre Değerlerini Kullanma

Bu komut dosyası -a veya -b gibi kesikli seçenekler kullanmaz. Komut satırında "normal" parametreleri kabul eder ve bunlara komut dosyası içinde değerler olarak erişilir.

 #!/bin/bash

# değişkenleri tek tek al
echo "Birinci Değişken: $1" 
echo "İki Değişken: $2" 
echo "Üç Değişken: $3"

# değişkenler arasında döngü
" $@" içindeki var için
yankı "$ var" 
tamamlamak

Parametrelere komut dosyası içinde $1 , $2 veya $3 değişkenleri olarak erişilir.

Bu metni bir düzenleyiciye kopyalayın ve “variables.sh” adlı bir dosya olarak kaydedin. chmod komutuyla çalıştırılabilir hale getirmemiz gerekecek. Bu adımı tartıştığımız tüm komut dosyaları için yapmanız gerekecek. Her seferinde uygun komut dosyasının adını değiştirin.

 chmod +x değişkenleri.sh 

bir betiği çalıştırılabilir yapmak için chmod komutunu kullanma

Betiğimizi parametresiz çalıştırırsak bu çıktıyı alırız.

 ./değişkenler.sh 

parametresiz bir komut dosyası çalıştırma

Komut dosyasının rapor edilecek hiçbir değeri olmadığı için hiçbir parametre iletmedik. Bu sefer bazı parametreler verelim.

 ./variables.sh nasıl geek yapılır 

parametreleri olarak üç kelime ile bir komut dosyası çalıştırma

Beklendiği gibi, $1 , $2 ve $3 değişkenleri parametre değerlerine ayarlandı ve bunların yazdırıldığını görüyoruz.

Bu tür bire bir parametre işleme, kaç tane parametre olacağını önceden bilmemiz gerektiği anlamına gelir. Komut dosyasının altındaki döngü, kaç parametre olduğu ile ilgilenmez, her zaman hepsi arasında döngü yapar.

Dördüncü bir parametre sağlarsak, bir değişkene atanmaz, ancak döngü yine de onu yönetir.

 ./variables.sh web sitesi nasıl yapılır 

yalnızca üçünü işleyebilen bir komut dosyasına dört parametre geçirmek

İki kelimenin etrafına tırnak işaretleri koyarsak, bunlar bir parametre olarak kabul edilir.

 ./variables.sh nasıl "geek olunur" 

tek bir parametre olarak ele alınması için iki komut satırı parametresinden alıntı yapmak

Tüm seçenek kombinasyonlarını, bağımsız değişkenli seçenekleri ve “normal” veri türü parametrelerini işlemek için komut dosyamıza ihtiyacımız olacaksa, seçenekleri normal parametrelerden ayırmamız gerekecek. Bunu, argümanlı veya argümansız tüm seçenekleri normal parametrelerin önüne yerleştirerek başarabiliriz.

Ama yürümeden koşmayalım. Komut satırı seçeneklerini işlemek için en basit duruma bakalım.

İşleme Seçenekleri

Bir while döngüsünde getopts kullanıyoruz. Döngünün her yinelemesi, komut dosyasına iletilen bir seçenek üzerinde çalışır. Her durumda, OPTION değişkeni getopts tarafından tanımlanan seçeneğe ayarlanır.

Döngünün her yinelemesinde getopts bir sonraki seçeneğe geçer. Başka seçenek kalmadığında, getopts false döndürür ve while döngüsü çıkar.

Bash Komut Dosyalarında Vaka İfadeleri Nasıl Kullanılır
İLGİLİ Bash Komut Dosyalarında Vaka İfadeleri Nasıl Kullanılır

OPTION değişkeni, case deyimi yan tümcelerinin her birindeki kalıplarla eşleştirilir. Case deyimi kullandığımız için, komut satırında seçeneklerin hangi sırayla sağlandığı önemli değildir. Her seçenek case ifadesine bırakılır ve uygun madde tetiklenir.

Case ifadesindeki tek tek tümceler, komut dosyası içinde seçeneğe özgü eylemleri gerçekleştirmeyi kolaylaştırır. Tipik olarak, gerçek dünya komut dosyasında, her cümlede bir değişken ayarlarsınız ve bunlar komut dosyasında daha ilerideki bayraklar olarak hareket ederek bazı işlevlere izin verir veya bunları reddeder.

Bu metni bir düzenleyiciye kopyalayın ve “options.sh” adlı bir komut dosyası olarak kaydedin ve yürütülebilir hale getirin.

 #!/bin/bash

getopts 'abc' SEÇENEĞİ; yapmak
  durumda "$OPTION" 
    a) 
      echo "Seçenek kullanılmış" ;;

    b)
      echo "Seçenek b kullanıldı"
      ;;

    c)
      echo "c seçeneği kullanıldı"
      ;;

    ?) 
      echo "Kullanım: $(taban adı $0) [-a] [-b] [-c]"
      çıkış 1
      ;;
  esac
tamamlamak

Bu while döngüsünü tanımlayan satırdır.

 getopts 'abc' SEÇENEĞİ; yapmak

getopts komutunu seçenekler dizisi takip eder. Bu, seçenek olarak kullanacağımız harfleri listeler. Seçenek olarak sadece bu listedeki harfler kullanılabilir. Bu durumda, -d geçersiz olur. Bu, ?) yan tümcesi tarafından yakalanır çünkü getopts bir soru işareti “ ? ” tanımlanamayan bir seçenek için. Bu olursa, terminal penceresine doğru kullanım yazdırılır:

 echo "Kullanım: $(taban adı $0) [-a] [-b] [-c]"

Kural olarak, bu tür doğru kullanım mesajında ​​bir seçeneği parantez “ [] ” içine almak, seçeneğin isteğe bağlı olduğu anlamına gelir. basename komutu, dosya adından tüm dizin yollarını çıkarır. Bash komut dosyalarında komut dosyası adı $0 içinde tutulur.

Bu betiği farklı komut satırı kombinasyonlarıyla kullanalım.

 ./options.sh -a
 ./options.sh -a -b -c
 ./options.sh -ab -c
 ./options.sh -cab 

anahtar tipi komut satırı seçeneklerini kabul edebilen bir komut dosyasını test etme

Gördüğümüz gibi, tüm test kombinasyonlarımız doğru bir şekilde ayrıştırıldı ve işlendi. Ya var olmayan bir seçeneği denersek?

 ./options.sh -d 

Kabuk ve komut dosyası tarafından bildirilen tanınmayan bir seçenek

Kullanım yan tümcesi tetiklenir, bu iyidir, ancak kabuktan bir hata mesajı da alıyoruz. Bu, kullanım durumunuz için önemli olabilir veya olmayabilir. Komut dosyasını, hata mesajlarını ayrıştırması gereken başka bir komut dosyasından çağırıyorsanız, kabuğun da hata mesajları oluşturması daha zor olacaktır.

Kabuk hata mesajlarını kapatmak çok kolaydır. Tek yapmamız gereken seçenekler dizisinin ilk karakteri olarak iki nokta üst üste ” : ” koymak.

Ya “options.sh” dosyanızı düzenleyin ve seçenekler dizisinin ilk karakteri olarak iki nokta üst üste ekleyin ya da bu betiği “options2.sh” olarak kaydedin ve yürütülebilir hale getirin.

 #!/bin/bash

getopts ':abc' SEÇENEĞİ; yapmak
  durumda "$OPTION" 
    a) 
      echo "Seçenek a kullanılmış" 
      ;;

    b)
      echo "Seçenek b kullanıldı"
      ;;

    c)
      echo "c seçeneği kullanıldı"
      ;;

    ?) 
      echo "Kullanım: $(taban adı $0) [-a] [-b] [-c]"
      çıkış 1
      ;;
  esac
tamamlamak

Bunu çalıştırdığımızda ve bir hata oluşturduğumuzda, herhangi bir kabuk mesajı olmadan kendi hata mesajlarımızı alıyoruz.

 ./options2.sh.sh -d 

Yalnızca komut dosyası tarafından bildirilen tanınmayan bir seçenek

Seçenek Bağımsız Değişkenleri ile getopts kullanma

getopts bir seçeneğin ardından bir argüman geleceğini söylemek için, seçenekler dizesindeki seçenek harfinin hemen arkasına iki nokta üst üste ” : ” koyun.

Seçenekler dizimizde “b” ve “c” yi iki nokta üst üste ile takip edersek, getopt bu seçenekler için argümanlar bekleyecektir. Bu betiği düzenleyicinize kopyalayın ve “arguments.sh” olarak kaydedin ve yürütülebilir hale getirin.

Seçenekler dizesindeki ilk iki nokta üst üste işaretinin kabuk hata mesajlarını bastırmak için kullanıldığını unutmayın; bunun argüman işlemeyle hiçbir ilgisi yoktur.

getopt bir seçeneği bir argümanla işlediğinde, argüman OPTARG değişkenine yerleştirilir. Bu değeri betiğinizin başka bir yerinde kullanmak istiyorsanız, onu başka bir değişkene kopyalamanız gerekir.

 #!/bin/bash

while getopts ':ab:c:' SEÇENEĞİ; yapmak

  durumda "$OPTION"
    a)
      echo "Seçenek a kullanılmış"
      ;;

    b)
      argB="$OPTARG"
      echo "Seçenek b ile birlikte kullanılır: $argB"
      ;;

    c)
      argC="$OPTARG"
      echo "c seçeneği ile kullanılan: $argC"
      ;;

    ?)
      echo "Kullanım: $(temel isim $0) [-a] [-b argümanı] [-c argümanı]"
      çıkış 1
      ;;
  esac

tamamlamak

Bunu çalıştıralım ve nasıl çalıştığını görelim.

 ./arguments.sh -a -b "nasıl geek yapılır" -c inceleme geek
 ./arguments.sh -c incelemegeek -a 

seçenek argümanlarını işleyebilen bir komut dosyasını test etme

Artık seçenekleri, komut satırında verildikleri sıraya bakılmaksızın, argümanlı veya argümansız olarak ele alabiliriz.

Peki ya normal parametreler? Daha önce, herhangi bir seçeneğin ardından bunları komut satırına koymamız gerektiğini bildiğimizi söylemiştik. Bakalım yaparsak ne olacak.

Karıştırma Seçenekleri ve Parametreler

Önceki komut dosyamızı bir satır daha içerecek şekilde değiştireceğiz. while döngüsünden çıkıldığında ve tüm seçenekler işlendiğinde normal parametrelere erişmeye çalışacağız. Değeri $1 olarak yazdıracağız.

Bu betiği “arguments2.sh” olarak kaydedin ve yürütülebilir hale getirin.

 #!/bin/bash

while getopts ':ab:c:' SEÇENEĞİ; yapmak

  durumda "$OPTION"
    a)
      echo "Seçenek a kullanılmış"
      ;;

    b)
      argB="$OPTARG"
      echo "Seçenek b ile birlikte kullanılır: $argB"
      ;;

    c)
      argC="$OPTARG"
      echo "c seçeneği ile kullanılan: $argC"
      ;;

    ?)
      echo "Kullanım: $(temel isim $0) [-a] [-b argümanı] [-c argümanı]"
      çıkış 1
      ;;
  esac

tamamlamak

echo "Bir değişken: $1"

Şimdi birkaç seçenek ve parametre kombinasyonunu deneyeceğiz.

 ./arguments2.sh dave
 ./arguments2.sh -bir davet
 ./arguments2.sh -a -c nasıl yapılır sorusu 

Seçenek argümanlarını kabul eden bir komut dosyasında standart parametrelere erişilemiyor

Yani şimdi sorunu görebiliriz. Herhangi bir seçenek kullanılır kullanılmaz, $1 1'dan sonraki değişkenler, seçenek bayrakları ve argümanları ile doldurulur. Son örnekte, $4 "dave" parametre değerini tutar, ancak kaç tane seçenek ve argüman kullanılacağını bilmiyorsanız, betiğinizde buna nasıl erişirsiniz?

Cevap, OPTIND ve shift komutunu kullanmaktır.

shift komutu, ilk parametreyi - türü ne olursa olsun - parametre listesinden atar. Diğer parametreler "karıştırılır", böylece parametre 2 parametre 1 olur, parametre 3 parametre 2 olur ve bu böyle devam eder. Ve böylece $2 $1 olur, $3 $2 olur ve bu böyle devam eder.

Bir sayı ile shift sağlarsanız, o kadar çok parametreyi listeden çıkarır.

OPTIND , seçenekleri ve argümanları bulundukça ve işlenirken sayar. Tüm seçenekler ve argümanlar işlendikten OPTIND , seçenek sayısından bir fazla olacaktır. Bu nedenle, parametre listesinden shift to trim (OPTIND-1) parametrelerini kullanırsak, $1 1'dan sonraki normal parametrelerle kalırız.

Bu betiğin yaptığı tam olarak bu. Bu betiği “arguments3.sh” olarak kaydedin ve yürütülebilir hale getirin.

 #!/bin/bash

while getopts ':ab:c:' SEÇENEĞİ; yapmak
  durumda "$OPTION"
    a)
      echo "Seçenek a kullanılmış"
      ;;

    b)
      argB="$OPTARG"
      echo "Seçenek b ile birlikte kullanılır: $argB"
      ;;

    c)
      argC="$OPTARG"
      echo "c seçeneği ile kullanılan: $argC"
      ;;

    ?)
      echo "Kullanım: $(temel isim $0) [-a] [-b argümanı] [-c argümanı]"
      çıkış 1
      ;;
  esac
tamamlamak

echo "Önce - birinci değişken: $1"
shift "$(($OPTIND -1))"
echo "Sonra - değişken bir: $1"
echo "Argümanların geri kalanı (işlenenler)"

"$@" içindeki x için
yapmak
  yankı $x
tamamlamak

Bunu bir seçenekler, argümanlar ve parametreler karışımı ile çalıştıracağız.

 ./arguments3.sh -a -c nasıl yapılır geek "dave dee" sersem gagalı mick tich 

Seçenek argümanlarını kabul eden bir komut dosyasında standart parametrelere doğru şekilde erişme

shift çağırmadan önce $1 1'ın “-a” tuttuğunu görebiliriz, ancak shift komutundan sonra $1 ilk seçenek olmayan, argüman olmayan parametremizi tutar. Seçenek ayrıştırma olmadan bir komut dosyasında olabildiğince kolay bir şekilde tüm parametreler arasında dolaşabiliriz.

Seçeneklere Sahip Olmak Her Zaman İyidir

Komut dosyalarındaki seçenekleri ve argümanlarını işlemenin karmaşık olması gerekmez. getopts ile komut satırı seçeneklerini, argümanları ve parametreleri tam olarak POSIX uyumlu yerel komut dosyalarının yapması gerektiği gibi işleyen komut dosyaları oluşturabilirsiniz.