OVH Cloud OVH Cloud

modification récente dans la façon d'écrire un test en sh ?

7 réponses
Avatar
Sébastien Kirche
Bonjour,

hier j'ai apporté une modification à un script sh que j'utilise depuis
au moins un an de façon régulière sans problème et là ça a coincé.

Il s'agit d'un script pour me construire le paramétrage iptables.

Le problème s'est posé sur deux tests if pour lesquels l'exécution m'a
retourné :
[: 242: ==: unexpected operator
[: 419: ==: unexpected operator

les deux numéros de ligne sont les fi du if.

Voici le premier par exemple :
if [ $DHCP == "yes" ] ; then
$IPTABLES -A udp_packets -p UDP -s $DHCP_SERVER --sport 67 \
--dport 68 -j ACCEPT
fi

DHCP vaut "no", les autres variables sont également renseignées.
L'interpréteur indiqué dans le script est #!/bin/sh

Je pense avoir trouvé qu'il faut écrire le test avec = au lieu de ==,
cependant je ne comprends pas pourquoi cela a fonctionné des mois avec
== et que tout à coup il ne veut pas.

Je mets à jour régulièrement les versions des logiciels installés sur
cette machine : est-ce qu'un tel changement a pu être fait dans sh ?

Merci de vos éclaircissements :)

--
Sébastien Kirche

7 réponses

Avatar
Vincent Bernat
OoO En cette fin de matinée radieuse du samedi 23 avril 2005, vers
11:16, Sébastien Kirche
disait:

if [ $DHCP == "yes" ] ; then


Colle :

if [[ $DHCP == "yes ]]; then ...

Je pense que cela va résoudre le problème.
--
BOFH excuse #194:
We only support a 1200 bps connection.

Avatar
FAb
Sébastien Kirche writes:

Bonjour,

hier j'ai apporté une modification à un script sh que j'utilise depuis
au moins un an de façon régulière sans problème et là ça a coincé.



DHCP vaut "no", les autres variables sont également renseignées.
L'interpréteur indiqué dans le script est #!/bin/sh

Je pense avoir trouvé qu'il faut écrire le test avec = au lieu de ==,
cependant je ne comprends pas pourquoi cela a fonctionné des mois avec
== et que tout à coup il ne veut pas.

Je mets à jour régulièrement les versions des logiciels installés sur
cette machine : est-ce qu'un tel changement a pu être fait dans sh ?

Merci de vos éclaircissements :)


% bash --version
GNU bash, version 2.05b.0(1)-release (i386-redhat-linux-gnu)
Copyright (C) 2002 Free Software Foundation, Inc.
% DHCP % [ $DHCP == 'ok' ] && echo ok || echo ko
bash: [: ==: unary operator expected
ko
% DHCP=toto
% [ $DHCP == 'ok' ] && echo ok || echo ko
ko
% DHCP=ok
% [ $DHCP == 'ok' ] && echo ok || echo ko
ok

Quand la variable est vide il couine, on dirait qu'il gère la variable «vide»
comme pas de variable.

la doc info précise :

`STRING1 == STRING2'
True if the strings are equal. `=' may be used in place of `=='
for strict POSIX compliance.


FAb

Avatar
jaco
FAb wrote:

Quand la variable est vide il couine, on dirait qu'il gère la variable
«vide» comme pas de variable.


C'est entre autres pour ça qu'une ancienne convention consiste à mettre
un X devant les parties droite et gauche :

if [ "X$DHCP" = "Xyes" ] ...

la doc info précise :

`STRING1 == STRING2'
True if the strings are equal. `=' may be used in place of `=='
for strict POSIX compliance.


Et elle fait bien... La comparaison de chaînes est "=", pas "==", qui
est un C-isme.
--
Jaco

Avatar
David LE BOURGEOIS
Bonjour,


Bonjour.

hier j'ai apporté une modification à un script sh que j'utilise depuis
au moins un an de façon régulière sans problème et là ça a coincé.

Il s'agit d'un script pour me construire le paramétrage iptables.

Le problème s'est posé sur deux tests if pour lesquels l'exécution m'a
retourné :
[: 242: ==: unexpected operator
[: 419: ==: unexpected operator

les deux numéros de ligne sont les fi du if.

Voici le premier par exemple :
if [ $DHCP == "yes" ] ; then
$IPTABLES -A udp_packets -p UDP -s $DHCP_SERVER --sport 67
--dport 68 -j ACCEPT
fi


Protéger les variables par des " est une bonne habitude.

$ foo $ [ "$foo" = "bar" ] && echo OK || echo KO
KO
$ foo="a"
$ [ "$foo" = "bar" ] && echo OK || echo KO
KO
$ foo="bar"
$ [ "$foo" = "bar" ] && echo OK || echo KO
OK

Aussi, une autre manière de procéder :

$ grep -E "if.*[.*x.*=" /etc/init.d/proftpd
if [ "x$PIDFILE" = "x" ];
if [ "x$RUN" = "xyes" ] ; then
if [ "x$INETD" = "xyes" ] ; then
if [ "x$INETD" = "xyes" ] ; then
if [ "x$RUN" = "xyes" ] ; then
if [ "x$INETD" = "xyes" ] ; then
if [ "x$INETD" = "xyes" ] ; then
if [ "x$RUN" = "xyes" ] ; then
if [ "x$INETD" = "xyes" ] ; then

--
David LE BOURGEOIS

Avatar
Sébastien Kirche
Le 23 avr 2005, David LE BOURGEOIS a dit :

Protéger les variables par des " est une bonne habitude.


Merci à tous pour vos conseils.

*Mais* (et je me suis peut-être mal exprimé) les deux tests qui ont posé
problème étaient déjà rédigés comme cela et n'ont jamais protesté
auparavant.

Ma modification d'hier a consisté à rajouter une règle de routage d'un
port à un endroit du script qui n'avait rien à voir avec les 2 tests en
question. Et je n'ai pas non plus modifié la valeur des variables qui
sont testées.

D'où mon interrogation si c'était faux avant, de pourquoi ça n'a pas
gueulé avant...

--
Sébastien Kirche

Avatar
Eric Jacoboni
In article , SÈbastien Kirche
wrote:


D'où mon interrogation si c'était faux avant, de pourquoi ça n'a pas
gueulé avant...


Ce n'était pas faux pour ton shell puisqu'il accepte la forme "==".

Peut-être qu'après ta modif, ta variable DHCP se retrouve vide, d'où le
problème qui survient maintenant ?

Avatar
Stephane Chazelas
2005-04-23, 12:34(+02), Eric Jacoboni:
FAb wrote:

Quand la variable est vide il couine, on dirait qu'il gère la variable
«vide» comme pas de variable.


C'est entre autres pour ça qu'une ancienne convention consiste à mettre
un X devant les parties droite et gauche :

if [ "X$DHCP" = "Xyes" ] ...


le X n'est pas pour ca:

if [ "$DHCP" = yes ]

marchera toujours avec les shells POSIX.

if [ "$DHCP" = yes ]

ne marchera pas toujours avec certains shells/"[" (Bourne, ash,
vieilles versions de certains autres shells), mais ce ne sera
pas dans le cas ou $DHCP sera vide mais dans les cas ou il
contiendra quelque chose comme "(" ou "!".

[ yes = "$DHCP" ]

devrait toujours marcher.

la doc info précise :

`STRING1 == STRING2'
True if the strings are equal. `=' may be used in place of `=='
for strict POSIX compliance.


Et elle fait bien... La comparaison de chaînes est "=", pas "==", qui
est un C-isme.


Note que dans (( ... )), le double = est obligatoire, puisque le
simple egal signifie assignment.

if (( (a = 1) == b )); then

Que l'on ecrit de maniere POSIX:

if a=1; [ "$a" -eq "$b" ]; then

Ni (( ... )) ni [[ ... ]], ni [ ... == ... ] ne sont POSIX.

--
Stéphane