Почему rm * (1) * удаляет все файлы в каталоге?


47

Я ожидал, что:

$ rm *(1)*

удалил бы все файлы, содержащиеся (1)в имени. Я ошибался. Он удалил все файлы в каталоге.

Почему?


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

Ответы:


51

От man bash:

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

У вас есть выражение glob, которое соответствует файлам, начинающимся с нуля или более 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 У вас есть ссылка на ошибку, связанную с этой регрессией? Спасибо
Basic

2
@ Базовик, вот , пожалуйста . Чет еще не ответил.
Стефан Шазелас

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для проверки вашего шаблона, если вы не совсем уверены, что это работает :)


К вашему сведению: {это скобка, (это пара (или круглая скобка).
Микель

Ах, спасибо. Я не являюсь носителем английского языка, поэтому я склонен их путать :)
Мартин фон Виттих,

6
На британском языке: {= фигурная скобка, (= круглая скобка, [= квадратная скобка. На американском языке: {= скобка, (= paren, [= скобка. Немного смущает. Если вам когда-нибудь понадобится проверить, что-то называется, Jargon File - ASCII весьма полезен.
Микель

4
@Mikel Спасибо, я также проверил здесь, так что теперь я знаю о цветочных скобках и белки !

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