Perché rm * (1) * rimuove tutti i file in una directory?


47

Mi aspettavo che:

$ rm *(1)*

rimuoverebbe tutti i file che contengono (1)nel nome. Mi sbagliavo. Ha rimosso tutti i file nella directory.

Perché?


5
Ogni volta che uso rmcon un modello, lo precedo sempre echoprima di eseguire il comando effettivo. L'abitudine mi ha salvato più di una volta (da allora, a 6 anni circa, confondendo la differenza tra DEL A: *.*e DEL *.* A:).
Gerrit,

Risposte:


51

Da man bash:

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

Hai un'espressione glob che corrisponde ai file che iniziano con zero o più 1s - che è tutti i file.

Un modo semplice per disabilitare questo comportamento sconvolgente è \sfuggire alle parentesi:

rm *\(1\)*

Altrimenti puoi usare shopt -u extglobper disabilitare il comportamento e shopt -s extglobper riattivarlo:

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

Si noti che, come dice Stephane , extglobè abilitato bash-completiondisabilitando in modo tale che le funzioni di completamento potrebbero non funzionare correttamente.


7
Nota che extglobnon è attivo per impostazione predefinita ma è attivato da bash_completion se lo hai installato e abilitato. bashnon ha portata locale per le opzioni come zshfa.
Stéphane Chazelas,

1
Si noti inoltre che bash-4.3ha una regressione in quanto *(1)*espande anche i file nascosti.
Stéphane Chazelas,

@StephaneChazelas Hai un link per il bug relativo a quella regressione? Grazie
Basic

2
@Basic, qui si va . Chet non ha ancora risposto.
Stéphane Chazelas,

9

Ciò è probabilmente correlato extgloball'opzione shell. Se lo spengo, il modello produce un messaggio di errore:

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

Se lo accendo, sembra davvero corrispondere a tutto. La manpage documenta questi schemi, penso che siano correlati:

   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

Non vedo alcuna documentazione che specifichi cosa fanno le parentesi senza un protagonista. Ad ogni modo, puoi aggirare il problema citando le parentesi:

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

Inoltre, usa echoo lsper testare prima il tuo modello se non sei assolutamente sicuro che funzioni :)


Cordiali saluti: {è un tutore, è una parentesi ((o parentesi tonda).
Mikel,

Ah grazie. Non sono di madrelingua inglese, quindi tendo a confonderli :)
Martin von Wittich,

6
In inglese: {= parentesi graffa, (= parentesi tonda, [= parentesi quadra. In americano: {= parentesi graffa, (= parentesi , [= parentesi. Un po 'confuso. Se hai mai bisogno di controllare come si chiama qualcosa, Jargon File - ASCII è abbastanza utile.
Mikel,

4
@Mikel Grazie, ho controllato anche qui quindi ora so delle parentesi di fiori e di quelle scoiattolo !

In inglese indiano, {è una parentesi di fiori, [è una parentesi quadra ed (è una parentesi tonda o più comunemente solo parentesi. :-)
ShreevatsaR
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.