Je ne veux pas nécessairement la réponse, mais si quelqu'un pouvait me pointer vers de la littérature ou des exemples. Je voudrais le comprendre.
Lorsque j'exécute le script, je reçois une erreur:
Erreur de syntaxe près d'un jeton inattendu
fi
J'ai déduit que mon problème est dans ma if
déclaration en faisant mes if
commentaires et en ajoutant echo "$NAME"
qui affiche les noms dans le /etc/
.
Quand je fais des changements, retirez le #
de if
et fi
et ajouter #
à wc -c "$NAME"
, je reçois l'erreur de syntaxe I ci - dessus. J'ai ajouté ;
entre- ]
temps. Je suis également passé then
à la ligne suivante sans résolution.
#!/bin/bash
for NAME in /etc/*
do
if [ -r "$NAME" -af "$NAME" ] then
wc -c "$NAME"
fi
done
-af
censé faire?-a
est redondant car la condition est déjà incluse dans-f
. --- Quoi qu'il en soit, plusieurs conditions[ ]
(cette commande est également disponible en tant quetest
) doivent être jointes à l'aide d'opérateurs logiques comme-a
(et) ou-o
(ou), mais comme cela a été suggéré dans la réponse ci-dessous, il est préférable d'utiliser plusieurs commandes[ ]
(test
) et de joindre les utilisant des opérateurs shell comme&&
ou||
.Réponses:
Mots - clés comme
if
,then
,else
,fi
,for
,case
et ainsi de suite doivent être dans un endroit où le shell attend un nom de commande. Sinon, ils sont traités comme des mots ordinaires. Par exemple,imprime simplement
if
, il ne démarre pas une instruction conditionnelle.Ainsi, dans la ligne
le mot
then
est un argument de la commande[
(dont il se plaindrait s'il venait à s'exécuter). Le shell continue de chercher lethen
et trouve unefi
position de commande. Puisqu'il y enif
a toujours un qui le recherchethen
,fi
c'est inattendu, il y a une erreur de syntaxe.Vous devez mettre un terminateur de commande avant
then
afin qu'il soit reconnu comme mot-clé. Le terminateur de commande le plus courant est un saut de ligne, mais avantthen
, il est courant d'utiliser un point-virgule (qui a exactement la même signification qu'un saut de ligne).ou
Une fois que vous aurez corrigé cela, vous obtiendrez une autre erreur de la commande
[
car elle ne comprend pas-af
. Vous vouliez probablement direBien que les commandes de test ressemblent à des options, vous ne pouvez pas les regrouper comme ceci. Ce sont des opérateurs de la
[
commande et ils doivent chacun être un mot distinct (comme le font[
et]
).Soit dit en passant, bien que cela
[ -r "$NAME" -a -f "$NAME" ]
fonctionne, je recommande d'écrire soitou
Il est préférable de garder les
[ … ]
conditions simples car la[
commande ne peut pas distinguer facilement les opérateurs de l'opérande. Si$NAME
ressemble à un opérateur et apparaît dans une position où l'opérateur est valide, il peut être analysé en tant qu'opérateur. Cela ne se produira pas dans les cas simples présentés dans cette réponse, mais les cas plus complexes peuvent être risqués. L'écriture avec des appels séparés[
et l'utilisation des opérateurs logiques du shell évite ce problème.La seconde syntaxe utilise la
[[ … ]]
construction conditionnelle qui existe dans bash (et ksh et zsh, mais pas plain sh). Cette construction est une syntaxe spéciale, alors[
est analysée comme une autre commande, donc vous pouvez utiliser des choses comme à l'&&
intérieur et vous n'avez pas besoin de variables de citation , sauf dans les arguments à certains opérateurs de chaîne (=
,==
,!=
,=~
) (voir Quand des guillemets doubles nécessaire ? pour plus de détails).la source
if [[ 1 ]] then [[ 2 ]] fi
fonctionne dans ksh, pdksh et zsh.if(:)then(:)fi
fonctionne dans toutes les coquilles.Voir ce qui a changé comme suit
Si vous souhaitez supprimer toutes les commandes du bloc if, vous devez au moins y ajouter deux points, comme
ou version une ligne
if [ -r "$NAME" -a -f "$NAME" ]; then :; fi
la source
D'autres l'ont déjà souligné, mais si vous cherchez une référence officielle, alors RTM
Vous manquez le
;
Et la syntaxe de
list
est décrite dansman test
la source