Bash найти, только удалить файлы - порядок аргументов

Скажем, сегодня 8 апреля, и я выполняю следующее в bash.

cd /tmp
mkdir hello
touch -d 2015-04-01 hello

Затем, скажем, я хочу удалить все файлы в /tmp, которые старше одного дня, но НЕ каталоги, и я выполняю это:

find /tmp -mtime +1 -delete -type f

Почему каталог "привет" удаляется, если это не файл?

Спасибо!

2 ответа

Решение

Команда find выполняет выражение по порядку. поскольку -delete раньше -type, -type никогда не достигается Пытаться:

find /tmp -mtime +1 -type f -delete 
  • Полезный ответ Дэвида К. Ранкина использует правильный абстрактный термин выражение для ссылки на список аргументов, начинающийся с -mtime ...,
  • OP, напротив, называет этот список опциями [edit: в посте, который был удален].

Называть их "вариантами" понятно, но поскольку сам факт, что они не являются вариантами, является причиной проблемы, find Терминология и понятия заслуживают более пристального внимания:

  • Аргументы, которые следуют за входными путями, вместе называются выражением.
  • Выражение состоит из:
    • тесты (например, -type f)
    • действия (например, -delete)
    • варианты (например, -maxdepth 1) - обратите внимание, что такие параметры отличаются от стандартных параметров, которые должны предшествовать даже входным путям (например, find -L /tmp ...)
    • Примечание: выше GNU find терминология, которая более полезна, чем в спецификации POSIX. за find где все три конструкции называются одним именем, праймериз (BSD find также использует праймериз в своем man страница).
    • операторы: -a (-and) для логического И, -o (-or) для логического ИЛИ, и ! (-not) за отрицание; альтернативные формы в скобках не являются POSIX-совместимыми, но поддерживаются GNU и BSD find.
  • Операторы объединяют тесты и действия в логические выражения.
    • При отсутствии явных операторов тесты и действия объединяются неявным логическим И ( -a )
    • -a а также -o применить короткое замыкание (см. ниже)
    • Подвыражения могут быть сгруппированы с \( а также \) изменить приоритет (\ -экранирование - это защита скобок от интерпретации оболочкой).
    • Приоритет (самый высокий сначала): \(...\), !, -a, -o
  • Порядок имеет значение в отношении тестов и действий.
    • find варианты, напротив, не позиционные, а GNU find по умолчанию выдает предупреждение, если они не размещены перед тестами и действиями. Чтобы избежать предупреждения и для концептуальной ясности в целом, лучше сделать это.
  • Каждый тест и действие возвращает логическое значение, и применяется короткое замыкание:
    • В типичном случае - с -a подразумевается - это означает, что последующий тест и действия НЕ оцениваются, если предыдущий тест или действие вернули false:
      • find . -false -print # !! -print is NOT executed
    • Точно так же 2-й операнд -o (-or) выражение НЕ выполняется, если 1-е вернуло true:
      • find . -print -o -print # !! 2nd -print is NOT executed
Другие вопросы по тегам