Kabuk komutunu açıklayın: shift $ (($ optind - 1))


30

Bir Linux üyesi değilim ama Projem için okumam gereken bazı Komut Dosyalarında sıkışıp kaldım. Bu komutun ne yaptığını kimse bana yardım edebilir mi?

shift $(($optind - 1))

3
Aşağıda belirtildiği gibi, OPTIND büyük harf olmalıdır ve parantez içindeki '$' isteğe bağlıdır.
DarkHeart

Yanıtlar:


49

shift $((OPTIND-1))(Not OPTINDbüyük harf) normalde bir getopts whiledöngüden hemen sonra bulunur . $OPTINDtarafından bulunan seçeneklerin sayısıdır getopts.

Pauljohn32'nin yorumlarında da belirtildiği gibi, kesinlikle konuşursak, bir sonraki komut satırı argümanının OPTINDkonumunu verir .

GNU Bash Referans Kılavuzundan :

getopts optstring adı [args]

getoptsKonumsal parametreleri ayrıştırmak için kabuk komut dosyaları tarafından kullanılır. optstringtanınacak seçenek karakterlerini içerir; Eğer bir karakteri iki nokta üst üste takip ederse, seçeneğin boşlukla ayrılması gereken bir argüman olması beklenir. İki nokta üst üste (':') ve soru işareti ('?') Seçenek karakterleri olarak kullanılamaz. Her çağrıldığında, bir getoptssonraki seçeneği namevarsa kabuk değişken adına yerleştirir, yoksa başlatır ve değişkene işlenecek bir sonraki argümanın dizinidir OPTIND. OPTINDHer kabuk veya kabuk komut dosyası çağrıldığında 1 olarak başlatılır. Bir seçenek bir argüman gerektirdiğinde, getopts bu argümanı değişkene yerleştirir OPTARG. Kabuk sıfırlanmadıOPTIND otomatik olarak; getoptseğer yeni bir parametre seti kullanılacaksa, aynı arama çağrısına birden fazla çağrı arasında manuel olarak sıfırlanması gerekir .

Seçeneklerin sonuna gelindiğinde, getoptssıfırdan büyük bir geri dönüş değeriyle çıkar. OPTINDilk seçenek olmayan bağımsız değişkenin dizine ayarlanır ve ad '?' olarak ayarlanır.

getoptsNormalde konum parametreleri ayrıştırır, ancak daha fazla argümanlar içinde verilirse args, getoptsbunun yerine bu ayrıştırır.

shift n, n dizelerini konumsal parametreler listesinden
siler . Böylece , parametreler listesinden ayrıştırılan tüm seçenekleri kaldırır ve bu noktadan sonra komut dosyasına iletilen ilk seçenek olmayan argümana atıfta bulunacaktır.shift $((OPTIND-1))getopts$1

Güncelleştirme

Mikeserv'in yorumunda belirttiği gibi, shift $((OPTIND-1))güvensiz olabilir. İstenmeyen sözcük bölme vs.'yi önlemek için tüm parametre genişletmelerinin çift alıntı yapılması gerekir. Yani komut için güvenli bir form

shift "$((OPTIND-1))"


Bu, yalnızca seçeneklerin tümü, herhangi bir konumsal argümandan önce meydana gelmesi durumunda işe yarayacak gibi görünüyor. Doğru?
Steve Jorgensen

@SteveJorgensen: Evet, doğru. OTOH, isteğe bağlı olmayan argümanların ardından seçenekleri koymak sh / bash kurallarına aykırıdır. Genel olarak, bir çizgi ile başlamayan ilk argümanlar seçeneklerin sonunu belirtir ve bir çizgi ile başlayan sonraki argümanlar seçenek olarak kabul edilmez. Tüm programlar bu sözleşmeye uymaz, ancak yaparsanız hayatı çok daha kolay hale getirir. :)
PM 2Ring

@ SteveJorgensen: (devamı) Bu konu kısaca tartışılmaktadır. Neden bazı programlar işlenenleri seçeneklerden önce ayrıştırıyorlar? . Gilles’un Celada’nın cevabına yaptığı yorumda, bazı programlar (gibi find), seçenek dışı olduktan sonra seçeneklere izin veriyor gibi görünebilirler , fakat yapmazlar: bir çizgi ile başlayan operandlara sahiptirler.
PM 2Ring

Bu bilgi için teşekkürler (& edit) @mosvy Oldukça sıradışı IFS, ancak üzgün olmaktan daha güvenli olmak daha iyi. ;)
PM 2Ring

eğer @roaima IFS=0123456789, shift $((OPTIND-1))(tırnaklar olmadan) dönüşecek shift ""olan sessizce (yok sayılacak ksh) veya (bir hata üretir bashve dash).
mosvy

8

$((...))sadece bir şeyler hesaplar. Sizin durumunuzda $optintve 1 altkümelerinin değerini alır

shiftkonumsal parametreleri kaldırır. Sizin durumunuzda optint-1parametreleri kaldırır .

Daha fazla bilgi için bir göz help getopts, help shiften göz man bash"Aritmetik genişletmesi" ve özellikle google getopts.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.