Warum erhalte ich mit dem folgenden Shell-Skript Fehler?
syntax error near unexpected token `else'
Shell-Skript
echo "please enter username"
read user_name
echo "please enter password"
read -s pass
echo ${ORACLE_SID}
SID=${ORACLE_SID}
if ["${ORACLE_SID}" != 'Test'] then
sqlplus -s -l $USER_NAME/$PASS@$SID <<EOF
copy from scott/tiger@orcl insert EMP using select * from EMP
exit
EOF
else
echo "Cannot copy"
fi
Antworten:
Sie müssen die Bedingung
if
wie folgt kündigen :oder so:
Hinweis: Sie müssen auch Leerzeichen nach
[
und vor setzen]
.Der Grund für den
;
Zeilenumbruch ist, dass der Bedingungsteil derif
Anweisung nur ein Befehl ist. Jeder Befehl von beliebiger Länge, um genau zu sein. Die Shell führt diesen Befehl aus, überprüft den Beendigungsstatus des Befehls und entscheidet dann, ob dasthen
Teil oder daselse
Teil ausgeführt werden soll.Da der Befehl beliebig lang sein kann, muss eine Markierung vorhanden sein, um das Ende des Bedingungsteils zu markieren. Das ist die
;
oder die neue Zeile, gefolgt vonthen
.Der Grund für die Räume nach
[
, weil[
ein Befehl ist. In der Regel ein eingebautes der Shell. Die Shell führt den Befehl[
mit dem Rest als Parameter aus, einschließlich des]
obligatorischen letzten Parameters. Wenn Sie nach[
der Shell kein Leerzeichen setzen, versucht die Shell,[whatever
den Befehl auszuführen, und schlägt fehl.Der Grund für den Platz vor dem
]
ist ähnlich. Denn sonst wird es nicht als eigener Parameter erkannt.quelle
test.sh: line 6: [: missing
if
ist Syntax, es ist kein gewöhnlicher Befehl. Es ist ein reserviertes Wort. Im Gegensatz zu vielen anderen Programmiersprachen erkennt die Shell reservierte Wörter nicht überall, nur wenn sie das erste Wort eines Befehls sind (mit ein paar Feinheiten).if
das Syntax ist. Ich habe versucht zu kommunizieren, dass der Bedingungsteil vonif
nicht durch Syntax auf eine bestimmte Form beschränkt ist. Ich habe den Text bearbeitet. Ich hoffe es ist jetzt klarer.Sie können Ihre Shell-Skripte problemlos mit ShellCheck online überprüfen (auch als eigenständiges Tool verfügbar).
In diesem Fall wird darauf hingewiesen, dass die if-Anweisung nach
[
und vor Leerzeichen benötigt]
und dass Sie;
vorthen
derselben Zeile ein (oder ein neues) Zeichen benötigen .Wenn Sie dies behoben haben, wird Ihnen mitgeteilt, dass
USER_NAME
die Datei verwendet wird, ohne dass eine Initialisierung erforderlich ist. Dies liegt daran, dass Sie auch eineuser_name
Variable haben (case matters). Gleiches gilt fürPASS
undpass
.Es sagt Ihnen auch, dass Sie verwenden sollen
read -r
, um dasread
Zerfleischen zu unterbinden\
(was zum Beispiel für Kennwörter wichtig sein könnte) und dass Sie die Variablen beim Aufrufensqlplus
in doppelte Anführungszeichen setzen sollten, um zu verhindern, dass die Shell versehentlich Dateinamen verschiebt und Wörter aufteilt (dies ist wiederum wichtig, wenn Das Passwort enthält zum Beispiel Zeichen wie "Datei"*
oder Leerzeichen.Durch Einrücken des Codes wird er auch lesbarer:
Hier habe ich es auch möglich gemacht, Passwörter mit führenden oder nachfolgenden Leerzeichen zu verwenden, indem vorübergehend
IFS
eine leere Zeichenfolge für das Lesen des Passworts festgelegt wurderead
.Die Logik wurde auch geändert, um zu retten, wenn
$ORACLE_SID
/$sid
istTest
. Dadurch wird vermieden, dass sich der Hauptbetriebsteil des Skripts in einerif
Verzweigung befindet.quelle
if ([ x = x ]) then (echo yes) fi
auch funktioniert.if
Anweisungen mit[ ... ]
... :-)Wenn
sh
Sie schreiben , möchten SieBeim Schreiben
bash
Bitte beachten Sie die Leerzeichen. Zwischen
[[
und dem ersten Operator muss ein Leerzeichen stehen .quelle