Antworten:
Es gibt einen speziell für diesen Fall erstellten Befehl: yes
$ yes | ./script
Damit verbinden Sie den Ausgang von yes
mit dem Eingang von ./script
. Wenn ./script
nach Benutzereingaben gefragt wird, wird stattdessen die Ausgabe von abgerufen yes
. Die Ausgabe von yes
ist ein endloser Strom von y
gefolgt von einer neuen Zeile. Also im Grunde, als ob der Benutzer y
für jede Frage von eingibt ./script
.
Wenn Sie n
statt yes ( y
) no ( ) sagen möchten, können Sie dies folgendermaßen tun:
$ yes n | ./script
Beachten Sie, dass einige Tools die Option haben, immer yes
als Antwort zu fungieren . Siehe hier zum Beispiel: Umgehen der Ja / Nein-Aufforderung in 'apt-get upgrade'
Andere Eingabemethoden:
Wenn Sie genau wissen, wie viele von y
Ihrem Skript erwartet werden, können Sie dies folgendermaßen tun:
$ printf 'y\ny\ny\n' | ./script
Die Zeilenumbrüche ( \n
) sind die Eingabetasten.
Verwenden Sie printf
anstelle von yes
, um die Eingabe feiner zu steuern:
$ printf 'yes\nno\nmaybe\n' | ./script
Beachten Sie, dass der Benutzer in einigen seltenen Fällen nicht die Eingabetaste nach dem Zeichen drücken muss. in diesem Fall lassen Sie die Zeilenumbrüche weg:
$ printf 'yyy' | ./script
Der Vollständigkeit halber können Sie hier auch ein Dokument verwenden :
$ ./script << EOF
y
y
y
EOF
Oder wenn Ihre Shell einen Here-String unterstützt :
$ ./script <<< "y
y
y
"
Oder Sie können eine Datei mit einer Eingabe pro Zeile erstellen:
$ ./script < inputfile
Wenn der Befehl ausreichend komplex ist und die oben genannten Methoden nicht mehr ausreichen, können Sie expect verwenden .
Hier ist ein Beispiel für ein supereinfaches Expect-Skript:
spawn ./script
expect "are you sure?"
send "yes\r"
expect "are you really sure?"
send "YES!\r"
expect eof
Technischer Nitpick:
Der hypothetische Befehlsaufruf, den Sie in Ihrer Frage angegeben haben, funktioniert nicht:
$ ./script < echo 'yyyyyyyyyyyyyy'
bash: echo: No such file or directory
Dies liegt daran, dass die Shell-Grammatik einen Umleitungsoperator an einer beliebigen Stelle in der Befehlszeile zulässt. Für die Shell ist Ihre hypothetische Befehlszeile dieselbe wie die folgende:
$ ./script 'yyyyyyyyyyyyyy' < echo
bash: echo: No such file or directory
Das heißt, es ./script
wird mit dem Argument aufgerufen 'yyyyyyyyyyyyyy'
und die stdin wird von einer Datei mit dem Namen eingegeben echo
. Und bash beschwert sich, da die Datei nicht existiert.
cannot enable tty mode on non tty input
. Würdest du einen Workaround dafür kennen?
printf
Trick mit einer run
Datei versuche , deren Installation ich automatisieren muss, erhalte ich lediglich eine Fehlermeldung. Warning: Tried to connect to session manager, None of the authentication protocols specified are supported
Das Skript wird in einem neuen Terminal geöffnet und fordert mich auf, meine Eingaben wie gewohnt manuell einzugeben. Dies geschieht übrigens unter Debian. Irgendwelche Vorschläge?
Verwenden Sie den Befehl yes
:
yes | script
Auszug aus der Manpage:
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'.
Einige Dinge ( apt-get
zum Beispiel) akzeptieren spezielle Flags, um im unbeaufsichtigten Modus ausgeführt zu werden (und akzeptieren Standardeinstellungen). In diesem apt-get
Fall übergeben Sie einfach eine -y
Flagge. Dies hängt jedoch vollständig von Ihrem Skript ab.
Wenn Sie kompliziertere Dinge benötigen, können Sie Ihr Skript in ein Expect-Skript einbinden. Mit expect können Sie Ausgaben lesen und Eingaben senden, sodass Sie ziemlich komplizierte Dinge tun können, die andere Skripte nicht zulassen würden. Hier ist eines der Beispiele auf der Wikipedia-Seite :
# 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
Shell-Skript verwendet werden, oder? Oder gibt es einen Weg?
Im Shell-Skript können Sie auch den folgenden Trick von Spawn, Expect und Send verwenden
spawn script.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"
Im obigen Szenario müssen Sie jedoch den Ausdruck angeben, den Sie erwarten, während Sie das Skript ausführen. Weitere Beispiele finden Sie unter folgendem Link
Okay, dies ist möglicherweise keine sehr elegante Lösung, aber wenn Sie Ihre Optionen in eine separate Datei schreiben und sie dann als Eingabe an das Skript übergeben, funktioniert dies ebenfalls. Wenn Sie also eine neue Datei mit all Ihren Optionen erstellen (nennen Sie diese Datei 'options.in'), können Sie Ihr Skript ganz einfach ausführen ./script.sh < options.in
und verschiedene Optionsdateien nach Bedarf bearbeiten / erstellen.
options.in
Datei schreiben ? Kannst du ein Beispiel geben?
Ich habe ein Bash-Skript mit Dialog geschrieben und brauchte dies auch, um automatisch zu funktionieren. Ich habe das getan und es hat wie ein Zauber funktioniert.
# -Wy force signaturewipe (if exists)
echo "y" | sudo lvcreate -W y -n $lvName -L "$lvSize"G /dev/"$svg" >> $nfsUtilLog
Sie können Benutzereingaben für Ihr Skript cat
aus einer Textdatei bereitstellen , die folgendermaßen an Ihr Skript weitergeleitet wird bash
:
cat input.txt | bash your_script.sh
Fügen Sie einfach die gewünschten Benutzereingaben in Ihre input.txt-Datei ein, und wählen Sie die gewünschten Antworten aus - y, n, Ziffern, Zeichenfolgen usw.
-f
funktioniert die Option auch mit bestimmten Befehlen.