Чому rm * (1) * видаляє всі файли в каталозі?


47

Я очікував, що:

$ rm *(1)*

видалить усі файли, що містяться (1)в імені. Я помилявся. Він видалив усі файли в каталозі.

Чому?


5
Щоразу, коли я використовую rmшаблон, я завжди передую йому echoперед тим, як видавати фактичну команду. Звичка врятувала мене не один раз (з тих пір, як 6-річний або близько того, плутаючи різницю між DEL A: *.*і DEL *.* A:).
Герріт

Відповіді:


51

Від man bash:

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

У вас є глобальний вираз, який відповідає файлам, що починаються з нуля або більше 1s - а це всі файли.

Один з простих способів відключити цю поведінку, яка полягає в глобалізації, - це \уникнути дужок:

rm *\(1\)*

Інакше ви можете shopt -u extglobвідключити поведінку та shopt -s extglobповторно активувати її:

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

Зауважте, що, як каже Стефан , extglobйого вмикають bash-completionтаким чином відключаючи, що може призвести до неправильної роботи функцій завершення.


7
Зауважте, що extglobза замовчуванням не увімкнено, але увімкнено bash_completion, якщо у вас це встановлено та увімкнено. bashне має локальної області для варіантів, як zshце робиться.
Стефан Шазелас

1
Також зауважте, що bash-4.3регресія в цьому *(1)*розширює також приховані файли.
Стефан Шазелас

@StephaneChazelas У вас є посилання на помилку, пов'язану з цією регресією? Спасибі
Основний

2
@Basic, ось ти . Чет ще не відповів.
Стефан Шазелас

9

Це, ймовірно, пов’язано з extglobопцією оболонки. Якщо я вимкну його, шаблон видає повідомлення про помилку:

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

Якщо я його ввімкну, він, здається, відповідає всім. На сторінці на сторінці розміщені документи, я думаю, що вони пов'язані:

   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

Я не бачу жодної документації, яка б визначала круглі дужки без провідного символу. У будь-якому випадку ви можете обійти проблему, цитуючи паролі:

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

Також спочатку використовуйте echoабо lsпротестуйте свій шаблон, якщо ви не впевнені, що це працює :)


FYI: {є дугою, (є батьківською (або круглою дужкою).
Мікель

Ах, дякую. Я не є носієм англійської мови, тому я схильний їх плутати :)
Мартін фон Віттіч

6
Британською мовою: {= фігурна дужка, (= кругла дужка, [= квадратна дужка. По-американськи: {= brace, (= paren, [= bracket. Трохи заплутано. Якщо вам колись потрібно перевірити, як щось називається, файл Jargon - ASCII дуже корисний.
Мікель

4
@Mikel Спасибі, я також перевірив тут, так що тепер я знаю про квіткові дужки та білочки !

Індійською англійською мовою {- це квіткова дужка, [є квадратною дужкою і (є круглою дужкою або, звичайно, просто дужкою. :-)
ShreevatsaR
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.