OVH Cloud OVH Cloud

problème avec les patterns en KSH

3 réponses
Avatar
sblaisot
Bonjour,

j'ai le problème suivant en ksh. Le script suivant fonctionne
correctement :

-- test-OK.ksh --
#!/usr/bin/ksh
set -x
STRING="foobar"
if [[ "${STRING}" = @(foobar|barfoo) ]]; then
echo OK
else
echo notOK
fi
-- test-OK.ksh --

il me répond bien OK parce que foobar est bien dans le pattern.

localhost:~$ ./test-OK.ksh
+ STRING=foobar
+ echo OK
OK


par contre, je souhaite maintenant mettre le pattern dans une
variable. je fais donc le shell suivant :

-- test-notOK.ksh --
#!/usr/bin/ksh
set -x
STRING="foobar"
PATTERN="@(foobar|barfoo)"
if [[ "${STRING}" = ${PATTERN} ]]; then
echo OK
else
echo notOK
fi
-- test-notOK.ksh --

et la, ca ne fonctionne plus.
localhost:~$ ./test-notOK.ksh
+ STRING=foobar
+ PATTERN=@(foobar|barfoo)
+ echo notOK
notOK


je ne comprend pas ce que j'ai fais de travers. Le manuel semble
indiquer que la substitution des variables se fait avant le matching
des patterns.
problème reproductible sous linux avec pdksh et sous AIX 5.2 avec ksh,
mais non reproductible en AIX 4.3 (ksh) où les deux scripts réagissent
de la même manière.

j'ai fais un truc de travers ?

merci d'avance

--
sébastien

3 réponses

Avatar
Stephane CHAZELAS
Le 26 Sep 2003 03:29:14 -0700, Seabstien BLAISOT écrivait :
[...]
-- test-notOK.ksh --
#!/usr/bin/ksh
set -x
STRING="foobar"
PATTERN="@(foobar|barfoo)"
if [[ "${STRING}" = ${PATTERN} ]]; then
echo OK
else
echo notOK
fi
-- test-notOK.ksh --

et la, ca ne fonctionne plus.
localhost:~$ ./test-notOK.ksh
+ STRING=foobar
+ PATTERN=@(foobar|barfoo)
+ echo notOK
notOK


Ça marche avec ksh93 o+ (au moins).

Sinon, tu peux toujours t'en sortir avec eval:

if eval '[[ "$STRING" = '"$PATTERN ]]"; then...

Encore une erreur de design de ksh (meme opérateur pour
comparaison chaine à chaine et pattern matching), qu'encore une
fois bash a copié betement et qu'encore une fois zsh a contourné

$ A="No!" B="No?" ksh -c '[[ $A = $B ]] && echo "$A == $B"'
No! == No?
$ A="No!" B="No?" bash -c '[[ $A = $B ]] && echo "$A == $B"'
No! == No?
$ A="No!" B="No?" zsh -c '[[ $A = $B ]] && echo "$A == $B"'
# comparaison chaine à chaine
$ A="No!" B="No?" zsh -c '[[ $A = $~B ]] && echo "$A == $B"'
No! == No? # $~B on dit explicitement que $B est un pattern

Il y avait eu un thread là dessus sur la ML
Une réponse de David Korn:

| Date: Wed, 2 Jul 2003 11:27:10 -0400 (EDT)
| From: David Korn
| Message-Id:
| Subject: Re: File name patterns in variables
|
| > I want to put an extended file name pattern in a variable.
| >
| > The following works:
| >
| > flag='*T*'
| > files=(Maildir/cur/*:2,!($flag))
| >
| > The following does not work:
| >
| > flag='!(*T*)'
| > files=(Maildir/cur/*:2,$flag)
| >
| > How do I put the extended regular expressions in a variable?
| >
| > /Joe
| >
|
| Because of backwards compatibility and conformance concerns,
| ksh does not recognize extended patterns that result from
| macro expansion when performing file name expansion.
| This is documented in the KornShell Command and Programming Language book.
| They are recognized in other cases, for example
| [[ $x == $pattern ]]
| since this doesn't present conformance problems. However,
| if the user happens to have A variable whose value
| is say
| foo='+(x)'
| and uses
| echo $foo
| in a script, the current shell standard would require that the ouput is
| +(x)
|
| Interestingly, the case that you present would not create
| conformance problems and therefore, I have added to my
| todo list to allow expansions that occur inside (...) to
| be treated as patterns even for pathname expansion.
|
| This would also allow uses to do
| @($x)
| to match all files that match the pattern "$x" and would not
| present compatibility problems.
|
| Currently the only way around the problem is to use eval.
| eval files='(Maildir/cur/*:2,'$flag')'
| should work.
|
| David Korn
|

--
Stéphane

Avatar
Sebastien BLAISOT
On Fri, 26 Sep 2003 13:05:19 +0200, Stephane CHAZELAS wrote:


Ça marche avec ksh93 o+ (au moins).


Arghhh, évidemment, on a ksh 88f
Version M11/16/88f

Sinon, tu peux toujours t'en sortir avec eval:

if eval '[[ "$STRING" = '"$PATTERN ]]"; then...


effectivement, ca marche, merci pour le tuyau.

quelqu'un peut-il m'expliquer pourquoi, avec la meme version de ksh
(M11/16/88f dans les deux cas) ca fonctionne en AIX 4.3 et pas en AIX 5.2
????

très étrange ma fois. IBM aurait-il inclus un patch caché dans AIX 4.3
qu'il aurait retiré en 5.2 ??

--
sebastien

Avatar
Stephane CHAZELAS
Le Fri, 26 Sep 2003 16:40:01 +0200, Sebastien BLAISOT écrivait :
[...]
quelqu'un peut-il m'expliquer pourquoi, avec la meme version de ksh
(M11/16/88f dans les deux cas) ca fonctionne en AIX 4.3 et pas en AIX 5.2
????

très étrange ma fois. IBM aurait-il inclus un patch caché dans AIX 4.3
qu'il aurait retiré en 5.2 ??


Mystères, mystères
des logiciels propriétaires...

--
Stéphane