Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

(zsh) problème avec des wildcards

13 réponses
Avatar
mpg
Bonjour,

Certains trucs que j'avais l'habitude de faire sous bash ne semblent pas
marcher tels quels sous zsh. Soit par exemple un répertoire qui
contiendrait les fichiers

foo.tex foo.aux foo.log foo.pdf

Si, dans ce répertoire, je tape 'rm *.aux *.log *.dvi' zsh me répond qu'il
n'y a pas de correspondances pour *.dvi et en conséquence ne fait rien.

C'est un peu pénible car d'une part j'avais l'habitude d'avoir un alias de
ce genre pour nettoyer les fichiers intermédiaires de compilation LaTeX, ce
que je ne sais plus faire du coup, et d'autre part ça montre que je ne
comprends pas bien le développement des wildcards sous zsh, ce qui me
chagrine.

Quelqu'un peut-il m'expliquer ce qui se passe et comment faire ce que je
veux sur cet exemple ?

Manuel.

10 réponses

1 2
Avatar
Benoit Izac
Bonjour,

le 10/11/2007 à 18:14, mpg a écrit dans le message
<fh4ou6$ql2$ :

Certains trucs que j'avais l'habitude de faire sous bash ne semblent
pas marcher tels quels sous zsh. Soit par exemple un répertoire qui
contiendrait les fichiers

foo.tex foo.aux foo.log foo.pdf

Si, dans ce répertoire, je tape 'rm *.aux *.log *.dvi' zsh me rà ©pond
qu'il n'y a pas de correspondances pour *.dvi et en conséquence ne
fait rien.

C'est un peu pénible car d'une part j'avais l'habitude d'avoir un
alias de ce genre pour nettoyer les fichiers intermédiaires de
compilation LaTeX, ce que je ne sais plus faire du coup, et d'autre
part ça montre que je ne comprends pas bien le développement des
wildcards sous zsh, ce qui me chagrine.

Quelqu'un peut-il m'expliquer ce qui se passe et comment faire ce que
je veux sur cet exemple ?

Manuel.
^^^^^^

Effectivement, il faut le lire. ;-)

Regarde dans le man de zshexpn « FILENAME GENERATION », tu y trou veras
« NULL_GLOB » qui doit correspondre à ce que tu cherches.

--
Benoit Izac

Avatar
Fabienne Ducroquet

Bonjour,


Bonjour,

Quelqu'un peut-il m'expliquer ce qui se passe et comment faire ce que je
veux sur cet exemple ?


Ce qui se passe c'est que le comportement par défaut de zsh n'est
pas le même que celui de bash (tu devais t'en douter), mais il y a des
options pour le configurer, d'après zshexpn(1) :

The word is replaced with a list of sorted filenames that
match the pattern. If no matching pattern is found, the shell
gives an error message, unless the NULL_GLOB option is set, in
which case the word is deleted; or unless the NOMATCH option is
unset, in which case the word is left unchanged.

Toi tu veux que *.dvi soit ignoré s'il n'y a pas de dvi dans le
répertoire donc il suffit d'ajouter setopt nullglob dans ton fichier
~/.zshrc.

--
Fabienne

Avatar
Olivier Miakinen

Ce qui se passe c'est que le comportement par défaut de zsh n'est
pas le même que celui de bash (tu devais t'en douter), mais il y a des
options pour le configurer, d'après zshexpn(1) :

The word is replaced with a list of sorted filenames that
match the pattern. If no matching pattern is found, the shell
gives an error message, unless the NULL_GLOB option is set, in
which case the word is deleted; or unless the NOMATCH option is
unset, in which case the word is left unchanged.

Toi tu veux que *.dvi soit ignoré s'il n'y a pas de dvi dans le
répertoire donc il suffit d'ajouter setopt nullglob dans ton fichier
~/.zshrc.


Je suppose que l'option correspondant au comportement habituel de bash
serait plutôt NOMATCH, non ?

Avatar
Fabienne Ducroquet
Le Sun, 11 Nov 2007 10:50:21 +0100, Olivier Miakinen
Je suppose que l'option correspondant au comportement habituel de bash
serait plutôt NOMATCH, non ?


En effet, le comportement de bash correspond à unsetopt nullglob et
unsetopt nomatch, avec l'exemple de mpg ça efface bien ce qu'on veut
mais ça fait un message d'erreur s'il n'y a pas de fichier dvi par
exemple, l'option nullglob permet d'éviter d'avoir une erreur et pour ce
genre de choses je pense que c'est le comportement qu'on veut (avec ou
sans nomatch).

--
Fabienne

Avatar
mpg
Le (on) dimanche 11 novembre 2007 13:22, Fabienne Ducroquet a écrit
(wrote) :

Le Sun, 11 Nov 2007 10:50:21 +0100, Olivier Miakinen
Je suppose que l'option correspondant au comportement habituel de bash
serait plutôt NOMATCH, non ?


En effet, le comportement de bash correspond à unsetopt nullglob et
unsetopt nomatch, avec l'exemple de mpg ça efface bien ce qu'on veut
mais ça fait un message d'erreur s'il n'y a pas de fichier dvi par
exemple, l'option nullglob permet d'éviter d'avoir une erreur et pour ce
genre de choses je pense que c'est le comportement qu'on veut (avec ou
sans nomatch).

En effet, je ne cherche pas forcément à avoir le comportement de bash (sinon

j'utiliserai bash, hein), et nullglob résout bien mon problème.

Merci pour ta réponse !

Manuel.


Avatar
mpg
Le (on) dimanche 11 novembre 2007 01:10, Benoit Izac a écrit (wrote) :
Manuel.
^^^^^^

Effectivement, il faut le lire. ;-)

Aussi étrange que cela puisse paraître, on ne me l'avait encore jamais

faite :-)

M.


Avatar
Stephane Chazelas
On Sat, 10 Nov 2007 18:14:46 +0100, mpg wrote:
[...]
Certains trucs que j'avais l'habitude de faire sous bash ne semblent pas
marcher tels quels sous zsh. Soit par exemple un répertoire qui
contiendrait les fichiers

foo.tex foo.aux foo.log foo.pdf

Si, dans ce répertoire, je tape 'rm *.aux *.log *.dvi' zsh me répond qu'il
n'y a pas de correspondances pour *.dvi et en conséquence ne fait rien.

C'est un peu pénible car d'une part j'avais l'habitude d'avoir un alias de
ce genre pour nettoyer les fichiers intermédiaires de compilation LaTeX, ce
que je ne sais plus faire du coup, et d'autre part ça montre que je ne
comprends pas bien le développement des wildcards sous zsh, ce qui me
chagrine.

Quelqu'un peut-il m'expliquer ce qui se passe et comment faire ce que je
veux sur cet exemple ?
[...]


Changer les options pour que zsh se comporte comme bash est une
mauvaise idee. C'est encore une des erreurs de bash que zsh a
corrigees. bash, s'il n'y a pas de fichier .aux va passer la
chaine "*.aux" telle quelle a "rm". Ce n'est pas trop un
probleme pour "*.aux" et "rm", puisqu'alors, rm se contentera
d'un message d'erreur pour dire que le fichier "*.aux" n'existe
pas. Mais pour des trucs comme "rm -- *.[cC]", s'il n'y a pas de
fichier .c ou .C, mais qu'il y a un fichier qui s'appelle
"*.[cC]", celui-ci sera effacé.

En zsh, si tu veux exceptionnellement ignorer le fait qu'un des
patterns ne matche aucun fichier, tu peux faire:

rm -- *.log *.aux(N) *.pdf

Dans ce cas, s'il n'y a pas de fichier .aux, *.aux sera expandé
en rien-du-tout.

Sinon, en un peu plus coherent et moins dangereux que bash, il y
a le globbing à la csh, qu'en zsh on peut activer en faisant:

setopt CSH_NULL_GLOB

Dans ce cas,

Tu n'auras une erreur dans

rm -- *.log *.aux *.pdf

que si aucun des patterns ne matche. Dans les autres cas, les
patterns qui ne matchent pas sont supprimés.

--
Stephane

Avatar
mpg
Le (on) lundi 12 novembre 2007 18:12, Stephane Chazelas a écrit (wrote) :
Quelqu'un peut-il m'expliquer ce qui se passe et comment faire ce que je
veux sur cet exemple ?
[...]


Changer les options pour que zsh se comporte comme bash est une
mauvaise idee.


Tu noteras d'ailleurs que je n'ai pas demandé comme faire pour que zsh se
comporte comme bash, mais juste à comprendre assez sur l'expansion de
wildcards pour faire ce que je veux dans ce cas précis :)

C'est encore une des erreurs de bash que zsh a
corrigees. bash, s'il n'y a pas de fichier .aux va passer la
chaine "*.aux" telle quelle a "rm". Ce n'est pas trop un
probleme pour "*.aux" et "rm", puisqu'alors, rm se contentera
d'un message d'erreur pour dire que le fichier "*.aux" n'existe
pas.


Truc que je n'avais d'ailleurs jamais remarqué, vu que je faisais toujours
des trucs du genre rm -f *.a *.b où au moins un fichier *.a ou *.b
existait. Mais qui me paraît assez malsain maintenant que j'en ai pris
conscience.

Mais pour des trucs comme "rm -- *.[cC]", s'il n'y a pas de
fichier .c ou .C, mais qu'il y a un fichier qui s'appelle
"*.[cC]", celui-ci sera effacé.

Voilà, c'est ce que j'entends par malsain :)


En zsh, si tu veux exceptionnellement ignorer le fait qu'un des
patterns ne matche aucun fichier, tu peux faire:

rm -- *.log *.aux(N) *.pdf

Ça me plaît pas mal comme solution, vu que ça me permet de faire ça cas par

cas, plutôt que de changer globalement le comportement.

Dans ce cas, s'il n'y a pas de fichier .aux, *.aux sera expandé
en rien-du-tout.

Ce qui est parfaitement ce que je veux.


setopt CSH_NULL_GLOB

Est-ce équivalent à setopt null_glob, évoqué ailleurs dans ce fil ? Je

n'arrive d'ailleurs par à trouver la référence dans zshexpn(1)...

Dans ce cas,

Tu n'auras une erreur dans

rm -- *.log *.aux *.pdf

que si aucun des patterns ne matche. Dans les autres cas, les
patterns qui ne matchent pas sont supprimés.

Je pense que je vais plutôt utiliser (N) en fait. Par contre je n'ai pas

trop compris comment est déterminée la porté du flag (N), ni comment zsh
détermine si c'est un flag ou juste un groupe ne comportant qu'un (N) ?

Manuel.


Avatar
Vincent Lefevre
Dans l'article <47388981$0$5077$,
Stephane Chazelas écrit:

Changer les options pour que zsh se comporte comme bash est une
mauvaise idee. C'est encore une des erreurs de bash que zsh a
corrigees.


C'est d'abord une erreur de conception de POSIX, comme il y en a tant
d'autres.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
Nicolas George
Vincent Lefevre wrote in message
<20071113000631$:
C'est d'abord une erreur de conception de POSIX, comme il y en a tant
d'autres.


POSIX n'a fait que normaliser le comportement qui était déjà celui des
shells style Bourne.

1 2