Odpowiedzi:
Istnieje specjalnie utworzone polecenie dla tego przypadku: yes
$ yes | ./script
To robi to podłączyć wyjście yes
do wejścia ./script
. Więc kiedy ./script
poprosi o dane wejściowe użytkownika, zamiast tego otrzyma wynik yes
. Wynikiem yes
jest niekończący się strumień, y
po którym następuje nowa linia. Zasadniczo tak, jakby użytkownik wpisał y
każde pytanie ./script
.
Jeśli chcesz powiedzieć nie ( n
) zamiast tak ( y
), możesz to zrobić w następujący sposób:
$ yes n | ./script
Pamiętaj, że niektóre narzędzia mają opcję, aby zawsze przyjmować yes
jako odpowiedź. Zobacz tutaj na przykład: Ominięcie monitu o tak / nie w 'apt-get upgrade'
Inne metody wprowadzania danych wejściowych:
Jeśli wiesz dokładnie, ile y
oczekuje Twój skrypt, możesz to zrobić w następujący sposób:
$ printf 'y\ny\ny\n' | ./script
Nowe linie ( \n
) to klawisze Enter.
Używanie printf
zamiast yes
ciebie ma bardziej precyzyjną kontrolę wejścia:
$ printf 'yes\nno\nmaybe\n' | ./script
Zauważ, że w niektórych rzadkich przypadkach polecenie nie wymaga od użytkownika naciśnięcia klawisza Enter po znaku. w takim przypadku pozostaw nowe linie:
$ printf 'yyy' | ./script
Dla zachowania kompletności możesz również skorzystać z dokumentu tutaj :
$ ./script << EOF
y
y
y
EOF
Lub jeśli twoja powłoka obsługuje to ciąg tutaj :
$ ./script <<< "y
y
y
"
Lub możesz utworzyć plik z jednym wejściem w wierszu:
$ ./script < inputfile
Jeśli polecenie jest wystarczająco złożone, a powyższe metody już nie wystarczają, możesz użyć metody expect .
Oto przykład bardzo prostego skryptu oczekiwanego:
spawn ./script
expect "are you sure?"
send "yes\r"
expect "are you really sure?"
send "YES!\r"
expect eof
Techniczny nitpick:
Hipotetyczne wywołanie polecenia podane w pytaniu nie działa:
$ ./script < echo 'yyyyyyyyyyyyyy'
bash: echo: No such file or directory
Jest tak, ponieważ gramatyka powłoki pozwala operatorowi przekierowania w dowolnym miejscu wiersza poleceń. Jeśli chodzi o powłokę, twoja hipotetyczna linia poleceń jest taka sama jak ta linia:
$ ./script 'yyyyyyyyyyyyyy' < echo
bash: echo: No such file or directory
Oznacza to, ./script
że zostanie wywołany z argumentem, 'yyyyyyyyyyyyyy'
a standardowe wejście otrzyma dane wejściowe z pliku o nazwie echo
. I bash narzeka, ponieważ plik nie istnieje.
cannot enable tty mode on non tty input
. Czy znasz to obejście?
printf
podstępu z run
plikiem, który muszę zautomatyzować proces instalacji, wszystko, co się dzieje, to pojawia się komunikat o błędzie Warning: Tried to connect to session manager, None of the authentication protocols specified are supported
, a skrypt otwiera się w nowym terminalu i prosi mnie o ręczne wprowadzenie danych jak zwykle. Nawiasem mówiąc, dzieje się to na Debianie. Jakieś sugestie?
Użyj polecenia yes
:
yes | script
Fragment strony man:
NAME
yes - output a string repeatedly until killed
SYNOPSIS
yes [STRING]...
yes OPTION
DESCRIPTION
Repeatedly output a line with all specified STRING(s), or 'y'.
Niektóre rzeczy ( apt-get
na przykład) akceptują specjalne flagi do działania w trybie cichym (i akceptują wartości domyślne). W takim apt-get
przypadku po prostu podajesz mu -y
flagę. Zależy to jednak całkowicie od twojego skryptu.
Jeśli potrzebujesz bardziej skomplikowanych rzeczy, możesz owinąć swój skrypt skryptem oczekiwanym. Oczekiwanie pozwala odczytać dane wyjściowe i wysłać dane wejściowe, dzięki czemu można wykonywać dość skomplikowane czynności, na które nie pozwalałoby inne skrypty. Oto jeden z przykładów ze strony Wikipedii :
# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof
.sh
skryptem powłoki, prawda? Czy jest jakiś sposób?
W skrypcie powłoki możesz także użyć następującej sztuczki spawnowania, oczekiwania i wysyłania
spawn script.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"
Jednak w powyższym scenariuszu będziesz musiał podać frazę, której oczekujesz podczas wykonywania skryptu, aby uzyskać więcej przykładów, przejdź do następującego linku
Ok, to może nie być bardzo eleganckie rozwiązanie, ale jeśli napiszesz opcje w osobnym pliku, a następnie przekażesz je jako dane wejściowe do skryptu, to również zadziała. Jeśli więc utworzysz nowy plik ze wszystkimi opcjami (nazwij ten plik jako „options.in”), możesz łatwo uruchomić skrypt ./script.sh < options.in
i edytować / tworzyć różne pliki opcji odpowiednio.
options.in
plik? Czy możesz podać przykład?
Pisałem skrypt bash w Dialogu i potrzebowałem, aby stało się to również automatycznie. Zrobiłem to i zadziałało jak urok.
# -Wy force signaturewipe (if exists)
echo "y" | sudo lvcreate -W y -n $lvName -L "$lvSize"G /dev/"$svg" >> $nfsUtilLog
Możesz podać dane wejściowe użytkownika do skryptu za cat
pomocą pliku tekstowego przesyłanego strumieniowo do skryptu w bash
następujący sposób:
cat input.txt | bash your_script.sh
Po prostu umieść żądane dane wejściowe użytkownika w pliku input.txt, niezależnie od potrzebnych odpowiedzi - y, n, cyfry, ciągi itp.
-f
opcja działa dobrze z niektórymi poleceniami.