[bash] Bug ou feature ?

Le
JKB
Bonjour à tous,

Je viens de passer quelques jours à pister un bug dans un script
shell pas compliqué du tout et j'aimerais savoir s'il s'agit d'une
fonctionnalité ou d'un bug (et si c'est une fonctionnalité
m'expliquer pourquoi).

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin
QUEUE=/home/machin/queue

for i in $QUEUE/*.to_be_sent
do
echo $i
done

exit 0

Trivial me direz vous. Lorsque la queue est vide, je ne devrais
obtenir aucune réponse. Raté, j'obtiens un superbe :

/home/machin/queue/*.to_be_sent

sur la sortie standard (et pas sur la sortie d'erreur, ce qui est
logique, /home/machin/queue/*.to_be_sent est le contenu de $i !).

En revanche, si je remplace

for i in $QUEUE/*.to_be_sent

par

for i in $(ls $QUEUE/*.to_be_sent 2> /dev/null)

ça fonctionne. D'où ma question : pourquoi dans le premier cas
l'expansion ne se fait-elle pas comme je l'attends ? Le bash utilisé
est celui de la distribution Debian/Stable i386.

Merci de vos lumières,

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse
=> http://grincheux.de-charybde-en-scylla.fr
Questions / Réponses high-tech
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #24324631
JKB
Bonjour à tous,

Je viens de passer quelques jours à pister un bug dans un script
shell pas compliqué du tout et j'aimerais savoir s'il s'agit d'une
fonctionnalité ou d'un bug (et si c'est une fonctionnalité
m'expliquer pourquoi).

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin
QUEUE=/home/machin/queue

for i in $QUEUE/*.to_be_sent
do
echo $i
done

exit 0

Trivial me direz vous. Lorsque la queue est vide, je ne devrais
obtenir aucune réponse. Raté, j'obtiens un superbe :




Feature. Voir shopt -s nullglob dans la doc de bash.

--
Jean-Marc
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Alain Ketterlin
Le #24324621
JKB
[...]
#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin
QUEUE=/home/machin/queue

for i in $QUEUE/*.to_be_sent
do
echo $i
done

exit 0

Trivial me direz vous. Lorsque la queue est vide, je ne devrais
obtenir aucune réponse. Raté, j'obtiens un superbe :

/home/machin/queue/*.to_be_sent



C'est le comportement par défaut de bash (aucune idée si c'est
standard). Le man de bash dit :

Pathname Expansion
After word splitting, unless the -f option has been set, bash sc ans
each word for the characters *, ?, and [. If one of these charact ers
appears, then the word is regarded as a pattern, and replaced with an
alphabetically sorted list of file names matching the pattern. If no
matching file names are found, and the shell option nullglob is not
enabled, the word is left unchanged. If the nullglob option is s et,
and no matches are found, the word is removed. If the failglob sh ell
option is set, and no matches are found, an error message is prin ted
and the command is not executed. [...]

Si tu tiens à bash, alors nullglob est sûrement l'option que tu c herches.

-- Alain.
JKB
Le #24324611
Le Thu, 15 Mar 2012 10:27:08 +0100,
Alain Ketterlin
JKB
[...]
#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin
QUEUE=/home/machin/queue

for i in $QUEUE/*.to_be_sent
do
echo $i
done

exit 0

Trivial me direz vous. Lorsque la queue est vide, je ne devrais
obtenir aucune réponse. Raté, j'obtiens un superbe :

/home/machin/queue/*.to_be_sent



C'est le comportement par défaut de bash (aucune idée si c'est
standard). Le man de bash dit :

Pathname Expansion
After word splitting, unless the -f option has been set, bash scans
each word for the characters *, ?, and [. If one of these characters
appears, then the word is regarded as a pattern, and replaced with an
alphabetically sorted list of file names matching the pattern. If no
matching file names are found, and the shell option nullglob is not
enabled, the word is left unchanged. If the nullglob option is set,
and no matches are found, the word is removed. If the failglob shell
option is set, and no matches are found, an error message is printed
and the command is not executed. [...]

Si tu tiens à bash, alors nullglob est sûrement l'option que tu cherches.



Merci pour ces infos. J'avais raté ça dans la doc de bash.

Cordialement,

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Tonton Th
Le #24324711
On 03/15/2012 10:27 AM, Alain Ketterlin wrote:

Trivial me direz vous. Lorsque la queue est vide, je ne devrais
obtenir aucune réponse. Raté, j'obtiens un superbe :

/home/machin/queue/*.to_be_sent



C'est le comportement par défaut de bash (aucune idée si c'est
standard). Le man de bash dit :



Il me semble que le bug est dans le comportement
différent selon que stderr est redirigé ou pas.

--

Nous vivons dans un monde étrange/
http://foo.bar.quux.over-blog.com/
Hugues
Le #24324771
Hello,

Tu as eu ta réponse, par contre j'ai une remarque :


Ce cher JKB

for i in $(ls $QUEUE/*.to_be_sent 2> /dev/null)



ls sert à *formatter l'affichage*, et dépend énormément de
l'environnement utilisateur (LC_ALL, LC_DATE, etc..). Il ne doit en
aucun cas être utilisé pour du parsing !!

Si vraiment tu veux utiliser un outil de type "ls", utilise plutôt
"find" :

for i in $(find $QUEUE/ -name "*.to_be_sent" 2>/dev/null)


C'est bien plus propre.

Mes 2cts. ;)
--
Hugues Hiegel [http://www.hiegel.fr/~hugues/]
JKB
Le #24324761
Le Thu, 15 Mar 2012 11:20:46 +0100,
Hugues

Hello,

Tu as eu ta réponse, par contre j'ai une remarque :


Ce cher JKB

for i in $(ls $QUEUE/*.to_be_sent 2> /dev/null)



ls sert à *formatter l'affichage*, et dépend énormément de
l'environnement utilisateur (LC_ALL, LC_DATE, etc..). Il ne doit en
aucun cas être utilisé pour du parsing !!



Oui mais non. La première chose que je fais dans un script, c'est
positionner la localisation. Quant à ls, il me semble qu'il prend
automatiquement l'option -1 dans ce cas.

Si vraiment tu veux utiliser un outil de type "ls", utilise plutôt
"find" :

for i in $(find $QUEUE/ -name "*.to_be_sent" 2>/dev/null)


C'est bien plus propre.



Certes.

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Alain Ketterlin
Le #24324821
Tonton Th
On 03/15/2012 10:27 AM, Alain Ketterlin wrote:

Trivial me direz vous. Lorsque la queue est vide, je ne devrais
obtenir aucune réponse. Raté, j'obtiens un superbe :

/home/machin/queue/*.to_be_sent



C'est le comportement par défaut de bash (aucune idée si c'est
standard). Le man de bash dit :



Il me semble que le bug est dans le comportement
différent selon que stderr est redirigé ou pas.



Je ne vois pas de quel bug tu parles. S'il n'y a pas de fichiers, c'est
ls qui fait le travail (n'affiche rien sinon un message d'erreur, qui
part sur /dev/null).

-- Alain.
Gilles Pion
Le #24325981
Ref:

C'est le comportement par défaut de bash (aucune idée si c'est
standard).



C'est standard au sens Posix en tout cas:

http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13_03

"If the pattern contains an invalid bracket expression or does not match any
existing filenames or pathnames, the pattern string shall be left unchanged."
--
Gilles Pion
naddy
Le #24326381
Gilles Pion
>C'est le comportement par défaut de bash (aucune idée si c'est
>standard).

C'est standard au sens Posix en tout cas:



C'est aussi le comportement historique :

| If no file name is found that matches the pattern then the word
| is left unchanged.

http://www.freebsd.org/cgi/man.cgi?query=sh&apropos=0&sektion=0&manpath=Unix+Seventh+Edition&archÞfault&format=html

--
Christian "naddy" Weisgerber
Cyrille Lefevre
Le #24328691
Le 15/03/2012 11:20, Hugues a écrit :

Si vraiment tu veux utiliser un outil de type "ls", utilise plutà ´t
"find" :

for i in $(find $QUEUE/ -name "*.to_be_sent" 2>/dev/null)

C'est bien plus propre.



Bonjour,

à la différence que find est récursif et pas ls, et malheu reusement,
il n'y a pas d'option portable pour limiter la récursivité tel que le
GNUisme -maxdepth 1

Cordialement,

Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%
supprimer "%nospam% et ".invalid" pour me repondre.
Publicité
Poster une réponse
Anonyme