EOF kullanmadan bash betiğinden metin girişini otomatikleştirme


10

Ubuntu Linux kullanıyorum. Diyelim ki bir program var myprogram. Bu program kullanıcıdan giriş yapmasını ister; özellikle, kullanıcı istendiğinde bir tamsayı yazmalı ve tuşuna basmalıdır Enter. Bir bash betiği kullanarak bu işlemi otomatikleştirmek istiyorum. Özellikle, yürütmek istiyoruz myprogram100 kez (bir sayaç kullanarak, söylemek igider 1için 100). Her yürütme işleminde, istendiğinde myprogramgeçerli değerini girmek istiyorum i.

(Bu arada, hepsi sabit olacak ve böylece bash betiğinde belirtilen myprogramseçenekleri / anahtarları alır -options.)

Bu bash betiğinin eksik bir iskeleti şunlar olabilir:

#!/bin/bash
for i in {1..100}
do
   myprogram -options
done

Şimdi iprogram tarafından istendiğinde geçerli değeri girilecek şekilde yukarıdaki kodu değiştirmek istiyorum . Bunu yapmanın en iyi yolu nedir?

Ben kullanıyorum yazılımın web sitesi önerir kullanılarak <<EOFsonunda myprogram -optionshattı. Bu bash giriş kullanmak için "dosyanın sonuna" bakmasını söyler düşünüyorum. Ancak girdiyi dosyanın sonuna yerleştirmek istemezsem ne olur ? Ne hemen sonra koymak istiyorsanız <<veya <?

Bunun nedeni, işlerin daha karmaşık hale gelmesidir. Örneğin, jdoğrusal olmayan, sıralı olmayan bir şekilde değişen bir tamsayı sayacı ekleyebilirim. Sonra mevcut değerini beslemek isteyeyim jiçin myprogramher tekrarında, ama değeri jçağrısı arasında değişebilir myprogram -optionsve dosyanın sonuna EOF.

Önerin var mı?


Yanıtlar:


14

Neredeyse tüm programlar için, hem echo $i | myprogram -optionsve myprogram -options <<<$iprogramı besleyerek, çalışması gerekir $istandart girdi yoluyla.

<foofoostdin olarak adlandırılan dosyanın içeriğini kullanacaktır .

<<foobu ve yalnızca foostandart girdi olarak oluşan bir satır arasındaki metni kullanacaktır . Gilles'in dediği gibi bu bir belge (yorumlu metin); EOFaslında dosyanın sonu anlamına gelmez, sadece yaygın bir yorumlu betimleyicidir (bu örnekte "foo" kullanıyoruz).

<<<foostandart giriş olarak "foo" dizesini kullanır. Ayrıca bir değişken belirtebilirsiniz $foove kabuk, yukarıda gösterdiğim gibi içeriğini stdin olarak kullanır. Bu, bir yorumlamada olduğu gibi, tüm bir bloğun aksine kısa bir dize kullandığı için bir ittifak olarak adlandırılır. Herestrings bash'de çalışıyor, ama değil /bin/sh.


9

Bu web sitesi tarafından önerilen sözdizimine burada belge denir . Dosya programına giriş, içeren satırın hemen altında başlar <<EOFve komut dosyasının sonuna kadar değil, tam olarak metni içeren bir satırla sonlandırılır EOF(fazladan boşluk olmamasına dikkat edin). Bu arada, herhangi bir kabuk özel karakteri içermeyen herhangi bir uç işaretçisi kullanabilirsiniz: EOFbir anahtar kelime değil, sadece gelenekseldir.

#!/bin/bash
for i in {1..100}
do
   myprogram -options <<EOF
$i
EOF
   for j in {1..42}; do
     myprogram2 <<EOF
$i
$j
EOF
   done
done

diğer bir deyişle, bu bağlamda EOF , komut dosyasının gerçek sonu değil, dosya sonu işaretçisi anlamına gelir . "EOF" metni herhangi bir keyfi metindir - << karakterlerden hemen sonra ne kullanırsanız kullanın, şimdi belgenin sonunu gösterecektir. Ben tipik olarak EOF kullanın çünkü göze çarpıyor ve herenow belgesi içinde olması pek olası değildir, örneğin, ben programlı olarak kabuk komut dosyası (ben oldukça sık yapmak) üretiyorum.
cas

bu cesur EOF olmalıdır <underscore><underscore>EOF<underscore> <underscore>
cas

Bu tür belgeleri kullanarak, genellikle bitiş işaretçisini daha anlamlı bir şeye değiştirdim (ve "rastgele" eşleşme olasılığı daha düşük) END_OF_WHATEVER_FUNCTION. Bazen, alanı / boyutu "kurtarmaya" çalışmak gerçekten bir çaba kaybıdır çünkü gerçekte ne olduğuna dair belirsizliğe neden olur.
killermist

sleepSenaryoda okunan komutlar arasında nasıl olabilirsiniz ?
boltup_im_coding

@ unexpected62 Ne istediğini anlamıyorum. Muhtemelen bu sitede yeni bir soru sormalısınız. Yeterli bağlam verdiğinizden emin olun.
Gilles 'SO- kötü olmayı bırak'

3

burada yukarıda hem Kevin hem de Gilles tarafından belirtilen belgeler veya basit borular birçok durumda işe yarayacaktır.

Daha karmaşık durumlar için, Expect veya benzerlerine bakmak isteyebilirsiniz (örn. Expect :: Simple CPAN modülünün kullanımı çok kolay bir perl uygulamasıdır). kişisel olarak, perl modülünü tercih ediyorum (Expect itself tcl'dir) ancak birçok yaygın komut dosyası dili için uygulamalar vardır. Fikri çok shel bash yaparken while ve read kullanarak çok ilkel bir uygulama yazmak bile mümkündür .

Expect ve benzer araçların genel fikri, bir programın çıktısında belirli bir dize veya desen beklemek ve daha sonra istediğiniz girdiyi beslemektir.

Yaygın bir örnek olarak, "ogin:" dizesini "bekleyerek" (yani bekleyerek), oturum açma adını göndererek "word:" dizesini bekleyip parolayı göndererek oturum açma işlemini otomatikleştirmektir.

Son bir seçenek, eğer programımın kaynağına sahipseniz, bunu komut satırı seçeneği olarak vermek istediğiniz girişi almak için değiştirmektir. Bu biraz daha ön çalışma olabilir, ancak Expect ile uğraşmaktan veya bu şekilde kullanılmak üzere tasarlanmamış bir programa veri aktarmaktan çok daha az rahatsız edici olacaktır.

... ve ekinizi mystream'e geri akışa göndermeyi unutmayın :) Kodladığınız yolu beğenmedikleri halde, bu özelliği kendileri eklemek için yeterince fikir isteyebilirler. Memba geliştiricileri, taleplerinden veya şikayetlerinden ziyade popolarından inen ve katkıda bulunan insanları takdir etme eğilimindedir.

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.