Por que o rm * (1) * remove todos os arquivos em um diretório?

45

Eu esperava isso:

$ rm *(1)*

removeria todos os arquivos contendo (1) no nome. Eu estava errado. Ele removeu todos os arquivos no diretório.

Por quê?

    
por Eric Wilson 18.03.2014 / 14:05

2 respostas

51

De man bash :

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

Você tem uma expressão glob que corresponde a arquivos que começam com zero ou mais 1 s - que são todos os arquivos.

Uma maneira simples de desativar esse comportamento de globbing é \ escapar dos parênteses:

rm *\(1\)*

Caso contrário, você pode usar shopt -u extglob para desativar o comportamento e shopt -s extglob para reativá-lo:

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

Observe que, como Stephane diz , extglob é ativado por bash-completion , portanto, desativá-lo pode fazer com que as funções de conclusão não funcionem corretamente.

    
por 18.03.2014 / 14:13
9

Isso provavelmente está relacionado à opção extglob shell. Se eu desativá-lo, o padrão gerará uma mensagem de erro:

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

Se eu ligá-lo, parece corresponder a tudo. A manpage documenta esses padrões, acho que eles estão relacionados:

   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

Não vejo nenhuma documentação que especifique o parêntese sem um caractere principal. De qualquer forma, você pode contornar o problema citando os parentes:

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

Além disso, use echo ou ls para testar seu padrão primeiro se você não tiver certeza absoluta de que está funcionando:)

    
por 18.03.2014 / 14:14