Linux Shell Komut Dosyası Seçeneklerini Ayrıştırmak için getopts Nasıl Kullanılır
Yayınlanan: 2022-06-25 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.
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
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
seçeneklerini kabul eden bir komut dosyanız varsa, -c
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
Betiğimizi parametresiz çalıştırırsak bu çıktıyı alırız.
./değişkenler.sh
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
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
İki kelimenin etrafına tırnak işaretleri koyarsak, bunlar bir parametre olarak kabul edilir.
./variables.sh nasıl "geek olunur"
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.
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
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
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
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
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
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
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.