Avec le script shell suivant, pourquoi j'obtiens des erreurs
syntax error near unexpected token `else'
Script Shell
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
Réponses:
Vous devez mettre fin à la condition
if
suivante:ou comme ça:
Remarque: vous devez également mettre des espaces après
[
et avant]
.La raison du
;
saut de ligne ou est que la partie condition de l'if
instruction n'est qu'une commande. Toute commande de n'importe quelle longueur pour être précis. Le shell exécute cette commande, examine l'état de sortie de la commande, puis décide d'exécuter lathen
pièce ou laelse
pièce.Comme la commande peut être de n'importe quelle longueur, il doit y avoir un marqueur pour marquer la fin de la partie condition. C'est le
;
ou la nouvelle ligne, suivi dethen
.La raison des espaces après
[
est parce que[
c'est une commande. Habituellement, une coquille intégrée. Le shell exécute la commande[
avec le reste comme paramètres, y compris le]
dernier paramètre obligatoire. Si vous ne mettez pas d'espace après[
le shell, il tentera de s'exécuter en[whatever
tant que commande et échouera.La raison de l'espace avant le
]
est similaire. Sinon, il ne sera pas reconnu comme un paramètre à part entière.la source
test.sh: line 6: [: missing
if
est la syntaxe, ce n'est pas une commande ordinaire. C'est un mot réservé. Contrairement à de nombreux autres langages de programmation, le shell ne reconnaît pas les mots réservés partout, uniquement lorsqu'ils sont le premier mot d'une commande (avec quelques subtilités).if
c'est la syntaxe. J'essayais de communiquer que la partie condition de laif
n'est pas limitée à une certaine forme par la syntaxe. J'ai édité le texte. J'espère que c'est plus clair maintenant.Vous pouvez facilement vérifier vos scripts shell à l'aide de ShellCheck en ligne (également disponible en tant qu'outil autonome).
Dans ce cas, il indiquera que l'instruction if a besoin d'espaces, après
[
et avant]
, et que vous avez besoin d'un;
(ou d'un retour à la ligne) avant lethen
sur la même ligne.Lorsque vous aurez corrigé cela, il vous dira qu'il
USER_NAME
est utilisé sans être initialisé à quoi que ce soit. En effet, vous avez également uneuser_name
variable (le cas est important). Il en va de même pourPASS
etpass
.Il vous indique également d'utiliser
read -r
pour arrêter laread
manipulation\
(peut être important pour les mots de passe, par exemple), et que vous devez doubler les variables lors de l'appelsqlplus
pour empêcher le shell de faire accidentellement le remplacement de nom de fichier et le fractionnement de mot (encore une fois, cela est important si le mot de passe, par exemple, contient des caractères de remplacement de fichier comme*
, ou des espaces).Le retrait du code le rendra également plus lisible:
Ici, j'ai également permis d'utiliser des mots de passe avec des caractères d'espace de début ou de fin en définissant temporairement
IFS
une chaîne vide pour la lecture du mot de passeread
.La logique a également été modifiée pour renflouer si
$ORACLE_SID
/$sid
estTest
. Cela évite d'avoir la partie opérationnelle principale du script dans uneif
branche.la source
if ([ x = x ]) then (echo yes) fi
fonctionne également.if
instructions avec[ ... ]
... :-)Lors de l'écriture,
sh
vous voudriezLors de l'écriture
bash
Attention aux espaces s'il vous plaît. Il doit y avoir un espace entre le
[[
premier opérateur.la source