Bash'deki bir yardımcı programa zincirleme çağrıları parametrelendirme


12

Ben stdin gelen veri sütunlarını okuyan (onları bir yumuşatma efekti uygulayarak) sonra stdout çıktıları bir Bash kabuk kullanılan bir kara kutu UNIX programı var. UNIX borularla kullanıyorum,

generate | smooth | plot  

Daha düzgünleştirmek için, pürüzsüzlüğü tekrarlayabilirim, böylece Bash komut satırından çağrılabilir

generate | smooth | smooth | plot   

ya da

generate | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | plot

Bu çok tuhaflaşıyor. Bash sarıcı yapmak smoothve çıktısını smoothgelişigüzel bir şekilde yeni bir örneğe besleyebilmek istiyorum.

generate | newsmooth 5 | plot

onun yerine

generate | smooth | smooth | smooth | smooth | smooth | plot

İlk denemem, geçerli dizinde geçici dosyalar oluşturan ve bunları silen bir Bash betiğiydi, ancak yazma erişimi olan bir dizinde olmadığımda çirkinleşti ve ayrıca kesildiğinde çöp dosyaları bıraktı.

smoothProgramla ilgili herhangi bir argüman yok .

Çağrı sayısını parametreleştirmek için böyle bir programı "sarmanın" daha zarif bir yolu var mı?


1
Umarım örneğiniz, gerçek bir ihtiyaç değil, soru uğruna zorlanmış bir durumdur
arielnmz

Yanıtlar:


18

Özyinelemeli bir işleve sarabilirsiniz:

smooth() {
  if [[ $1 -gt 1 ]]; then # add another call to function
    command smooth | smooth $(($1 - 1)) 
  else
    command smooth # no further 
  fi
}

Bunu şu şekilde kullanırsınız:

generate | smooth 5 | plot

eşdeğer

generate | smooth | smooth | smooth | smooth | smooth | plot

Bu mükemmel, tam gerektiği gibi davranıyor. Ve şimdi bash "command" anahtar sözcüğünü öğrendim.
Diane Wilbor


5

İstediğiniz smoothkomut miktarı kadar virgül yazmayı göze alabiliyorsanız , kabuğun virgülle ayrılmış Brace Expansion'dan yararlanabilirsiniz.

TP; DR

Örnek durumunuz için tüm komut satırı:

generate | eval 'smooth |'{,,,,} plot

Not:

  • daha fazla veya daha az tekrarını istiyorsanız virgül ekleyin veya kaldırın smooth |
  • daha |önce yok plotçünkü smooth |Brace Expansion tarafından üretilen son dizeye dahil
  • ayrıca smoothaçık küme ayından önce belirtilen sabit bölüme doğru şekilde ekleyebildiğiniz sürece argümanlar da sağlayabilirsiniz ; her durumda onları komutun tüm tekrarlarına sağlayacağınızı unutmayın

Nasıl çalışır

Virgülle ayrılmış Ayraç Genişletme, her biri belirli bir sabit parça artı belirtilen değişken parçalardan oluşan dizeleri dinamik olarak oluşturmanıza olanak tanır. Ürettiği gibi değişken parçalar olduğu kadar çok dize a{b,c,d}üretir ab ac ad.

Buradaki küçük hile, boş değişken parçaların bir listesini yapmayı tercih ederseniz , örneğin parantez içindeki virgüllerle, Brace Genişletme yalnızca sabit parçanın kopyalarını üretecektir. Örneğin:

smooth{,,,,}

üretecek:

smooth smooth smooth smooth smooth

4 virgülün 5 smoothdize ürettiğini unutmayın . Bu Brace Expansion'ın işleyiş şekli: virgül artı bir tane kadar dizgi üretir.

Senin durumda Tabii bir de ihtiyaç |her ayıran smooth, yani sadece sabit kısmen eklemek ama kabuğu olması gerektiği gibi alıntı özen değil bir defada yorumlamak. Yani:

'smooth|'{,,,,}

üretecek:

'smooth|' 'smooth|' 'smooth|' 'smooth|' 'smooth|'

Sabit parçayı daima açık desteğin hemen yanına yerleştirmeye dikkat edin , yani ' ve ile arasında boşluk olmamalıdır {.

(Sabit parçayı oluşturmak için, sabit parçadaki kabuk değişkenlerini genişletmeniz gerekiyorsa, tek tırnak yerine çift tırnak kullanabileceğinizi de unutmayın. Bazı kabuğun özel karakterleri oluştuğunda gereken ekstra çıkışa dikkat edin. çift ​​tırnaklı bir dize içinde).

Bu noktada eval , kabuğun nihayetinde olması gereken pipelined komutu olarak yorumlayabilmesi için bu dizeye bir uygulamanız gerekir.

Böylece, hepsini özetlemek gerekirse, örnek durumunuz için tüm komut satırı şöyle olacaktır:

generate | eval 'smooth |'{,,,,} plot

1
Bu, çağrının parametrelendirildiği yerlerde kullanılırsa önemli güvenlik sorunları vardır. Yinelemeli bash işlevi ve yinelemeli “eval” string oluşturma konusunda cevabımı görün : Hangisi daha iyi performans gösterir? Over Over Taşması.
Charles Duffy

1
@CharlesDuffy evalBiri değerlendirmek için güvenilmez, sterilize edilmemiş, dizeler sağladığında, yani bağladığınız durum gibi "bilinmeyen" içerik taşıyabilen değişkenlerle kullanıldığında , zımni risklerle ilgili endişelerinizi tamamen kabul ediyorum . Öte yandan, evalkomutların hızlı "sıhhi tesisat" için de çok kullanışlı olabilir, özellikle komut isteminde kullanıldığında, eldeki durum gibi görünüyorsa, buradaki evalgirdi yalnızca kullanıcı tarafından manuel olarak yazılan bir değişmez dize olurdu kişi
LL3

Zaten başka bir yerde görüldüğü gibi, her zaman eval striddialı ve aptalca bir şeyle değiştirebilirsiniz . /dev/stdin <<<str. Bu sadece aptallar üzerinde bir izlenim yaratmakla kalmaz, aynı zamanda @CharlesDuffy'ı sırtınızdan da koruyacaktır ;-)
pizdelect

1
@pizdelect, LL3'ün önceki yorumunu dikkatlice okuyabilirsiniz - dengeli, incelikli ve akıllıca. (Gerçekten de, benim kendi başlangıç açıklama Eğer görmezden gibi görünüyor nüansları sahipti; kritik bir ayrım olduğunu "çağrısı parametre belirlenmiştir durumlarda kullanıldığı takdirde": LL3 en örneği değildir parametrelendirilir güvenli yapma).
Charles Duffy
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.