Ich bin ziemlich neu in Shell-Skripten, aber ich möchte ein einfaches Skript schreiben, in dem die Bash-Datei je nach Benutzereingabe eine andere Textzeile wiedergibt. Zum Beispiel, wenn das Skript den Benutzer fragt "Sind Sie da?" und die Benutzereingabe ist "Ja" oder "Ja", dann würde das Skript so etwas wie "Hallo!" wiedergeben. Wenn die Benutzereingabe jedoch "Nein" oder "Nein" lautet, gibt das Skript etwas anderes wieder. Und schließlich, wenn die Benutzereingabe etwas anderes als Ja / Ja oder Nein / Nein ist, würde das Skript "Bitte antworten Sie mit Ja oder Nein" wiedergeben. Folgendes habe ich bisher:
echo "Are you there?"
read $input
if [ $input == $yes ]; then
echo "Hello!"
elif [ $input == $no ]]; then
echo "Are you sure?"
else
echo "Please answer yes or no."
fi
Unabhängig von der Eingabe erhalte ich jedoch immer die erste Antwort ("Hallo!")
Außerdem möchte ich Text in die Sprache integrieren (wie ich es bei anderen Bash-File-Projekten mit Festival getan habe). In anderen Bash-Dateien habe ich es so gemacht:
echo "Hello!"
echo "Hello!" | festival --tts
Gibt es eine Möglichkeit, dies in die obige Eingabeaufforderung if then / yes no aufzunehmen? Vielen Dank im Voraus, ich verwende dies, um einfache Bash-Dateien zu erstellen und mir selbst beim Lernen zu helfen.
quelle
set -x
oben auszuführen , um die Diagnoseausgabe anzuzeigen.Antworten:
Das Hauptproblem ist hier:
In bash ist normalerweise
$foo
der Wert der Variablenfoo
. Hier möchten Sie nicht den Wert, sondern den Namen der Variablen, also sollte es nur sein:Ebenso in den
if
Tests,$yes
und$no
sollte gerechtyes
und seinno
, da Sie nur die Zeichenfolgenyes
undno
dort wollen.Sie können
case
hier eine Anweisung verwenden, die es (IMHO) einfacher macht, mehrere Fälle basierend auf Eingaben durchzuführen:Sie können die beiden
echo
Anweisungen und die Verwendung vonfestival
in eine Funktion einschließen, um zu vermeiden, dass Sie sich wiederholen:Mit
$input
ersetzt bash dies durch seinen Wert, der anfangs nichts ist. Derread
Befehlslauf lautet also:Und
read
standardmäßig speichert die Eingabe in den VariablenREPLY
. Wenn Sie möchten, können Sie dieinput
Variable also vollständig entfernen und$REPLY
stattdessen verwenden$input
.Schauen Sie sich auch die
select
Aussage in Bash an.quelle
while true; do...done
Schleife, mitbreak
Anweisung direkt danachecho "Hello!"
.select
Aussage ist! In einerselect
Anweisung wird der Benutzer wiederholt aufgefordert, eine der verfügbaren Optionen auszuwählen. Basierend auf diesen Optionen können Sie dann entscheiden, ob Siebreak
dieselect
Anweisung verlassen oder die Schleife fortsetzen möchten. Siehe Beispiel: paste.ubuntu.com/p/Ztp3XGCKtFTL; DR : fix Syntaxfehler, sicherzustellen , dass Sie tatsächlich nicht leere Variablen in haben
[
Test, und eine Funktion zum Rohr durchstehentee
zufestival
.Soweit zum Siebdrucken und zur Ausgabe an
festival
, ich persönlich würde das Skript in eine Funktion und Rohr alles wickeltfestival
, mittee
dazwischen (welchem Text sowohl auf Bildschirm und Rohr sendet).Es müssen jedoch drei Syntaxprobleme behoben werden:
read $input
sollte seinread input
. Die$
Symbol-Dereferenzierungsvariable in Shell-Skripten (dh sie$input
wird durch das ersetzt, wasinput
gilt).yes
undno
Variablen deklariert. Was Sie tun sollten, ist ein Zeichenfolgenvergleich:[ "$input" == "yes" ]
]]
inelif
Warum Sie die
Hello!
ganze Zeit bekommen, liegt genau an den ersten beiden Aufzählungspunkten. Bevorread $input
die Variableinput
nicht existiert, führen Sie nur eine Leistung ausread
(dh eine nicht vorhandene Variable$input
wird in eine leere Zeichenfolge dereferenziert, wobei nur derread
Befehl dort verbleibt ). Was auch immer Sie eingeben, wird in derREPLY
Variablen gespeichert , dieread
verwendet wird, wenn kein Variablenname angegeben wurde. Und weilyes
keine Variable existiert, wird diese auch durch eine leere Zeichenfolge ersetzt. So wird in Wirklichkeit[ $input == $yes ]
so behandelt, wie[ "" == "" ]
es immer wahr ist.Das feste Skript sollte wie folgt aussehen:
Denken Sie daran, die Variablen in Anführungszeichen zu setzen und sich über den Unterschied zwischen
=
und==
im Testbefehl zu informieren .quelle
cmatrix
scheinen aus dem tragbaren Zeichensatz zu stammen, daher sehe ich kein Problem mit anderen Gebietsschema-Zeichen wie im "echten" Matrixfluss. Aber ich bin mir nicht sicher, wiefestival
das funktionieren würde, es wäre nur eine Menge Kauderwelsch. Aber theoretisch würde es gut funktionieren.Ein dritter Ansatz wäre, für jeden Fall eine gemeinsame Variable zuzuweisen und letztendlich auf diese Variable einzuwirken. Ich bin mir nicht sicher, wie häufig dieser Ansatz in Bash ist, aber in anderen Programmiersprachen ist er ziemlich Standard.
Auch
shopt -s nocasematch
in Verbindung mit[[
zum Vergleich von Zeichenfolgen ohne Berücksichtigung der Groß- und Kleinschreibung.Damit auch
YES
undNO
werden als gültige Eingabe getreten.shopt
[[
quelle