Pourquoi rm * (1) * supprime-t-il tous les fichiers d'un répertoire?

47

Je m'attendais à ce que:

$ rm *(1)*

supprimerait tous les fichiers contenant (1)le nom. J'avais tort. Il a supprimé tous les fichiers du répertoire.

Pourquoi?

Eric Wilson
la source
5
Chaque fois que j'utilise rmun motif, je le précède toujours echoavant d'exécuter la commande réelle. L'habitude m'a sauvé plus d'une fois (depuis, à l'âge de 6 ans, confondant la différence entre DEL A: *.*et DEL *.* A:).
gerrit

Réponses:

51

De man bash:

*(pattern-list)
                 Matches zero or more occurrences of the given patterns

Vous avez une expression globale qui correspond aux fichiers commençant par zéro ou plus 1s - ce qui correspond à tous les fichiers.

Un moyen simple de désactiver ce comportement de regroupement consiste à \échapper aux parenthèses:

rm *\(1\)*

Sinon, vous pouvez utiliser shopt -u extglobpour désactiver le comportement et shopt -s extgloble réactiver:

shopt -u extglob
rm *(1)*
shopt -s extglob

Notez que comme Stéphane le dit , il extglobest activé en bash-completionle désactivant, ce qui peut empêcher les fonctions d’achèvement de fonctionner correctement.

Graeme
la source
7
Notez que cette extgloboption n'est pas activée par défaut mais est activée par bash_completion si vous l'avez installé et activé. bashn'a pas de portée locale pour les options comme le zshfait.
Stéphane Chazelas
1
Notez également qu’il bash-4.3existe une régression qui *(1)*développe également les fichiers cachés.
Stéphane Chazelas
@StephaneChazelas Avez-vous un lien pour le bogue relatif à cette régression? Merci
Basic
2
@Basic, ici vous allez . Chet n'a pas encore répondu.
Stéphane Chazelas
9

Ceci est probablement lié à l' extgloboption shell. Si je l'éteins, le motif produit un message d'erreur:

martin@dogmeat:~$ shopt -u extglob
martin@dogmeat:~$ shopt extglob
extglob         off
martin@dogmeat:~$ echo *(1)*
bash: syntax error near unexpected token `('

Si je l'allume, il semble en effet correspondre à tout. La page de manuel documente ces modèles, je pense qu’ils sont liés:

   If the extglob shell option is enabled using the shopt builtin, several
   extended  pattern  matching operators are recognized.  In the following
   description, a pattern-list is a list of one or more patterns separated
   by a |.  Composite patterns may be formed using one or more of the fol
   lowing sub-patterns:

          ?(pattern-list)
                 Matches zero or one occurrence of the given patterns
          *(pattern-list)
                 Matches zero or more occurrences of the given patterns
          +(pattern-list)
                 Matches one or more occurrences of the given patterns
          @(pattern-list)
                 Matches one of the given patterns
          !(pattern-list)
                 Matches anything except one of the given patterns

Je ne vois aucune documentation qui spécifie ce que font les parenthèses sans un caractère principal. Quoi qu’il en soit, vous pouvez contourner le problème en citant les parens:

martin@dogmeat ~ % echo *\(1\)*
A(1)b

Aussi, utilisez echoou lstestez d’abord votre motif si vous n’êtes pas absolument sûr que ça marche :)

Martin von Wittich
la source
FYI: {est un corset, (est un paren (ou parenthèse ronde).
Mikel
Ah merci. Je ne parle pas anglais, donc j'ai tendance à les confondre :)
Martin von Wittich
6
En britannique: {= accolade, (= accolade ronde, [= accolade. En américain: {= accolade, (= paren, [= parenthèse. Un peu déroutant. Si vous avez besoin de vérifier comment quelque chose s'appelle, Jargon File - ASCII est très utile.
Mikel
4
@ Mikel Merci, j'ai également vérifié ici, donc maintenant je connais les brackets de fleurs et ceux en forme d' écureuil !
En anglais indien, {est un support de fleur, [est un support carré et (est un support rond ou plus simplement un support. :-)
ShreevatsaR