Przekazywanie argumentów do programu interaktywnego w sposób nieinteraktywny


115

Mam skrypt bash, który wykorzystuje readpolecenie do interaktywnego odczytywania argumentów poleceń, na przykład opcji tak / nie. Czy istnieje sposób wywołania tego skryptu w skrypcie nieinteraktywnym, przekazując domyślne wartości opcji jako argumenty?

To nie jest tylko jedna opcja, którą muszę przekazać do interaktywnego skryptu.


2
Jeśli czyta ze stdin, możesz potokować wejście
lc.

4
Ponieważ pytanie to ma wiele powtórzeń, warto zwrócić uwagę, że nie ma znaczenia, w jakim języku napisany jest program interaktywny. Mógłby to być program w C, który czyta standardowe wejście, aplikacja Erlang lub cokolwiek innego. Jest coś, co uruchamia się z wiersza poleceń i nieprzyjemnie wymaga interaktywnego wprowadzania danych, a chciałbyś to zautomatyzować.
tripleee

Oczywiście, jeśli masz kontrolę nad nieprzyjemną aplikacją, przepisz ją tak, aby mogła odczytywać odpowiedzi nieinteraktywnie (poprzez plik konfiguracyjny, opcje wiersza poleceń lub cokolwiek). Jest to znacznie bardziej niezawodne i odporne na zmianę kolejności lub sformułowania interaktywnych pytań.
tripleee

Odpowiedzi:


46

W przypadku bardziej złożonych zadań jest expect( http://en.wikipedia.org/wiki/Expect ). Zasadniczo symuluje użytkownika, możesz zakodować skrypt, jak reagować na określone wyniki programu i powiązane rzeczy.

Działa to również w takich przypadkach, w których sshzabronione jest przesyłanie do niego haseł.


8
... Chociaż właściwym rozwiązaniem w przypadku SSH jest przejście na uwierzytelnianie za pomocą klucza publicznego.
tripleee

154

Wiele sposobów

potwierdź swoje dane wejściowe

echo "yes
no
maybe" | your_program

przekierowanie z pliku

your_program < answers.txt

użyj dokumentu tutaj (może być bardzo czytelny)

your_program << ANSWERS
yes
no
maybe
ANSWERS

użyj ciągu tutaj

your_program <<< $'yes\nno\nmaybe\n'

5
Należy zwrócić uwagę, że działa to tylko wtedy, gdy program czyta standardowe wejście. Niektóre programy robią wszystko, co w ich mocy, aby np. Interaktywnie czytać hasła, nawet jeśli standardowym wejściem jest potok. W przypadku haseł ma to sens ze względów bezpieczeństwa; chociaż niektóre programy interaktywne są po prostu źle zaprojektowane.
tripleee

@tripleee Zgodnie z tym, co powiedziałeś, w jaki sposób skrypt odczytuje hasła, na które stdin nie ma wpływu? Wiem, że możesz użyć readdo pobrania stdin, jakiej funkcji możesz użyć do tego, co opisałeś?
flow2k

W takim przypadku musisz sprawdzić, czy program, z którym próbujesz wejść w interakcję, ma specjalny sposób wysyłania do niego danych wejściowych (np. Sshpass, ssh-agent), czy też użyj funkcji oczekiwania do skryptu interakcji.
glenn jackman

2
Programy takie jak Expect uruchamiają klienta pod pseudo-tty, gdzie wygląda na użytkownika, który ma terminal i klawiaturę na drugim końcu. Nie możesz tego zrobić zwykłą fajką.
tripleee

Ważna uwaga. To nie działa, jeśli dodamy spacje do podanych poleceń.
71GA

13

Możesz umieścić dane w pliku i przekierować je w następujący sposób:

$ cat file.sh
#!/bin/bash

read x
read y
echo $x
echo $y

Dane do skryptu:

$ cat data.txt
2
3

Wykonanie skryptu:

$ file.sh < data.txt
2
3

7

Chcę tylko dodać jeszcze jeden sposób. Znalazłem go gdzie indziej i jest dość proste. Powiedzmy, że chcę przekazać tak dla wszystkich podpowiedzi w wierszu poleceń dla polecenia „execute_command”, a następnie po prostu potokowałbym tak.

yes | execute_command

Spowoduje to użycie tak jako odpowiedzi na wszystkie pytania tak / nie.


2

Możesz także użyć printf, aby przesłać dane wejściowe do skryptu.

var=val
printf "yes\nno\nmaybe\n$var\n" | ./your_script.sh

To mnie uratowało. Dziękuję @spanchan.
sk001

0

może być inna alternatywa

echo "something" | tee /path/to/file

Polecenie tee drukuje na ekranie otrzymane dane wejściowe i jednocześnie zapisuje je w pliku.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.