Korzystam z systemu Ubuntu Linux. Załóżmy, że istnieje program o nazwie myprogram
. Ten program monituje użytkownika o wprowadzenie danych; w szczególności użytkownik musi wpisać liczbę całkowitą po wyświetleniu monitu i nacisnąć Enter. Chciałbym zautomatyzować ten proces za pomocą skryptu bash. W szczególności chciałbym wykonać myprogram
, powiedzmy, 100 razy (przy użyciu licznika, i
który przechodzi od 1
do 100
). Przy każdym wykonaniu myprogram
chciałbym wprowadzić bieżącą wartość i
po wyświetleniu monitu.
(Nawiasem mówiąc, myprogram
bierze opcje / przełączniki -options
, z których wszystkie będą stałe, a zatem określone w skrypcie bash.)
Niekompletny szkielet tego skryptu bash może być:
#!/bin/bash
for i in {1..100}
do
myprogram -options
done
Teraz chciałbym zmodyfikować powyższy kod, aby bieżąca wartość i
została wprowadzona po wyświetleniu monitu przez program. Jak najlepiej to zrobić?
Witryna oprogramowania, którego używam, sugeruje użycie <<EOF
na końcu myprogram -options
wiersza. Myślę, że to każe bashowi spojrzeć na „koniec pliku”, aby użyć danych wejściowych. Ale co jeśli nie chcę umieszczać danych wejściowych na końcu pliku? Co jeśli chciałbym umieścić go natychmiast po <<
lub <
?
Powodem jest to, że sprawy się skomplikują. Na przykład mogę wprowadzić licznik liczb całkowitych, j
który zmienia się w nieliniowy, niesekwencyjny sposób. Chciałbym następnie podać bieżącą wartość j
do myprogram
na każdej iteracji, ale wartość j
może się zmieniać między wywołaniem myprogram -options
a końcem pliku EOF
.
Masz jakieś sugestie?
Odpowiedzi:
Dla prawie wszystkich programach, zarówno
echo $i | myprogram -options
imyprogram -options <<<$i
powinno działać, przez karmienie program$i
poprzez standardowe wejście.<foo
użyje zawartości pliku o nazwiefoo
stdin.<<foo
użyje tekstu pomiędzy tym a wierszem składającym się wyłącznie zefoo
standardowego wprowadzania. To jest dokument tutaj (heredoc), jak powiedział Gilles;EOF
tak naprawdę nie oznacza końca pliku, to po prostu wspólny heredok (w tym przykładzie używamy „foo”).<<<foo
użyje ciągu „foo” jako standardowego wejścia. Możesz także określić zmienną$foo
, a powłoka użyje jej zawartości jako standard, jak pokazałem powyżej. Nazywa się to ciągiem znaków , ponieważ używa krótkiego łańcucha w przeciwieństwie do całego bloku, jak w heredoc. Herestrings działają w trybie bash, ale nie w/bin/sh
.źródło
Składnia zalecana przez tę stronę nazywa się tutaj dokumentem . Dane wejściowe do programu plików zaczynają się bezpośrednio poniżej wiersza zawierającego
<<EOF
i nie kończą się na końcu skryptu, ale wierszem zawierającym dokładnie tekstEOF
(uważaj, aby nie mieć dodatkowych białych znaków). Nawiasem mówiąc, możesz użyć dowolnego znacznika końcowego, który nie zawiera żadnego znaku specjalnego powłoki:EOF
nie jest słowem kluczowym, jest jedynie tradycyjny.źródło
END_OF_WHATEVER_FUNCTION
. Czasami próba „zaoszczędzenia” miejsca / rozmiaru jest w rzeczywistości stratą wysiłku, ponieważ powoduje niejasności co do tego, co się faktycznie dzieje.sleep
między komendami czytać ze skryptu?tutaj dokumenty, o których wspomnieli Kevin i Gilles powyżej, lub proste orurowanie będzie działać w wielu przypadkach.
W bardziej skomplikowanych sytuacjach możesz zajrzeć do Expect lub podobnego (np. Expect :: Simple CPAN moduł jest bardzo łatwą w użyciu implementacją perla). osobiście wolę moduł perla (spodziewam się, że to tcl), ale istnieją implementacje dla wielu popularnych języków skryptowych. Możliwe jest nawet napisanie bardzo prymitywnej implementacji pomysłu w sh lub bash przy użyciu while i read.
Ogólną ideą Expect i podobnych narzędzi jest oczekiwanie na określony ciąg znaków lub wzorzec na wyjściu programu, a następnie podawanie go bez względu na to, co chcesz.
Częstym przykładem jest automatyzacja logowania poprzez „oczekiwanie” (tj. Oczekiwanie) ciągu „ogin:”, wysłanie nazwy logowania, a następnie oczekiwanie ciągu „słowo:” i wysłanie hasła.
Ostatnią opcją, jeśli masz źródło mojego programu, jest po prostu zmodyfikować go, aby przyjąć dane wejściowe, które chcesz podać jako opcję wiersza poleceń. Może to być nieco więcej pracy z góry, ale będzie o wiele mniej irytujące niż bałagan z Oczekiwaniem lub przesyłanie danych do programu, który nie został zaprojektowany w taki sposób.
... i nie zapomnij przesłać łatki do myprogramu z powrotem w górę :) Nawet jeśli nie podoba ci się sposób, w jaki ją kodowałeś, może spodobać im się pomysł na dodanie tej funkcji. Deweloperzy z wyższego szczebla doceniają ludzi, którzy zrywają tyłki i wnoszą swój wkład, zamiast żądać lub narzekać.
źródło