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).
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
# marche qqsoit le shell case $i in *'*'*) break ;; esac
echo $i done
exit 0
alternative qui ne marche pas si $QUEUE contient des espaces :
pattern=$QUEUE/*.to_be_sent liste=$(echo $pattern) case $liste in "$pattern") exit ;; esac # ou # [[ -n $BASH_VERSION ]] && shopt -s extglob # [[ $liste = "$pattern ]] && exit for i in $liste; do echo $i; done
autre alternative qui devrait fonctionner avec des blancs dans $QUEUE :
pattern=$QUEUE/*.to_be_sent set -- $pattern # ou # set x $pattern # shift case $* in "$pattern") exit ;; esac # ou # [[ -n $BASH_VERSION ]] && shopt -s extglob # [[ $* = "$pattern ]] && exit for i; do echo $i; done
# marche qqsoit le shell
case $i in *'*'*) break ;; esac
echo $i
done
exit 0
alternative qui ne marche pas si $QUEUE contient des espaces :
pattern=$QUEUE/*.to_be_sent
liste=$(echo $pattern)
case $liste in "$pattern") exit ;; esac
# ou
# [[ -n $BASH_VERSION ]] && shopt -s extglob
# [[ $liste = "$pattern ]] && exit
for i in $liste; do echo $i; done
autre alternative qui devrait fonctionner avec des blancs dans $QUEUE :
pattern=$QUEUE/*.to_be_sent
set -- $pattern
# ou
# set x $pattern
# shift
case $* in "$pattern") exit ;; esac
# ou
# [[ -n $BASH_VERSION ]] && shopt -s extglob
# [[ $* = "$pattern ]] && exit
for i; do echo $i; done
# marche qqsoit le shell case $i in *'*'*) break ;; esac
echo $i done
exit 0
alternative qui ne marche pas si $QUEUE contient des espaces :
pattern=$QUEUE/*.to_be_sent liste=$(echo $pattern) case $liste in "$pattern") exit ;; esac # ou # [[ -n $BASH_VERSION ]] && shopt -s extglob # [[ $liste = "$pattern ]] && exit for i in $liste; do echo $i; done
autre alternative qui devrait fonctionner avec des blancs dans $QUEUE :
pattern=$QUEUE/*.to_be_sent set -- $pattern # ou # set x $pattern # shift case $* in "$pattern") exit ;; esac # ou # [[ -n $BASH_VERSION ]] && shopt -s extglob # [[ $* = "$pattern ]] && exit for i; do echo $i; done
Cyrille Lefevre. -- mailto:Cyrille.Lefevre-news% supprimer "%nospam% et ".invalid" pour me repondre.
Hugues
Ce cher Cyrille Lefevre <cyrille.lefevre-news% a posté :
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 malheureusement, il n'y a pas d'option portable pour limiter la récursivité tel que le GNUisme -maxdepth 1
Et ! -iwholepath "*/*" ?
-- Hugues Hiegel [http://www.hiegel.fr/~hugues/]
Ce cher Cyrille Lefevre <cyrille.lefevre-news%nospam@laposte.net.invalid> a posté :
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 malheureusement,
il n'y a pas d'option portable pour limiter la récursivité tel que le
GNUisme -maxdepth 1
Ce cher Cyrille Lefevre <cyrille.lefevre-news% a posté :
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 malheureusement, il n'y a pas d'option portable pour limiter la récursivité tel que le GNUisme -maxdepth 1
Et ! -iwholepath "*/*" ?
-- Hugues Hiegel [http://www.hiegel.fr/~hugues/]
Gilles Pion
Ref: <jk0jmg$1gsc$ de Cyrille Lefevre
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 malheureusement, il n'y a pas d'option portable pour limiter la récursivité tel que le GNUisme -maxdepth 1
Une solution tordue mais portable ("-prune" est Posix)
(le "/." et le "-print" sont importants pour que cela fonctionne) -- Gilles Pion
Ref: <jk0jmg$1gsc$1@talisker.lacave.net> de Cyrille Lefevre
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 malheureusement,
il n'y a pas d'option portable pour limiter la récursivité tel que le
GNUisme -maxdepth 1
Une solution tordue mais portable ("-prune" est Posix)
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 malheureusement, il n'y a pas d'option portable pour limiter la récursivité tel que le GNUisme -maxdepth 1
Une solution tordue mais portable ("-prune" est Posix)