🐛 Типичные ошибки урока 15

К оглавлению урока

⚡ Топ-3 ошибки

  1. find без кавычек: find . -name *.txt — оболочка раскрывает *.txt до вызова find. Правильно: find . -name "*.txt"
  2. locate с устаревшей базой: файл создан, но locate его не находит. Решение: sudo updatedb перед поиском.
  3. Забытый grep -v grep: ps -ef | grep bioset | wc -l включает строку самого grep в счёт. Правильно: добавить | grep -v grep

Ошибка 1: find без кавычек в -name

Симптом

Команда находит не те файлы или выдаёт ошибку "paths must precede expression".

Неправильно

find . -name *.txt

Правильно

find . -name "*.txt"

Почему

Оболочка bash раскрывает glob-шаблон *.txt до вызова команды. Если в текущей директории есть файлы a.txt b.txt, команда превращается в find . -name a.txt b.txt — и find видит два аргумента после -name, что является ошибкой. Кавычки отключают раскрытие шаблона в оболочке и передают его «как есть» в find.

Ошибка 2: locate находит устаревшие данные (или не находит новый файл)

Симптом

Только что созданный файл не находится через locate. Или locate находит файл, который уже был удалён.

Почему

locate работает по базе данных, которая строится в фоне раз в день (через cron). Все изменения файловой системы, произошедшие после последнего обновления базы, в поиске не отражаются.

Решение

sudo updatedb   # обновить базу данных locate
locate myfile   # теперь найдёт актуальные результаты

Когда использовать find вместо locate

Если нужна актуальная информация о файлах — используйте find. locate хорош для быстрого поиска по имени в стабильных каталогах.

Ошибка 3: Забытый grep -v grep при подсчёте процессов

Симптом

Счётчик процессов показывает на 1 больше, чем должен.

Неправильно

ps -ef | grep bioset | wc -l

Правильно

ps -ef | grep bioset | grep -v grep | wc -l

Почему

Сама строка grep bioset в момент выполнения тоже является процессом, и её вывод попадает в результаты ps -ef — потому что строка процесса grep содержит слово "bioset". grep -v grep исключает строки, содержащие слово "grep", убирая из счёта сам процесс поиска.

Ошибка 4: Неверный синтаксис -exec

Симптом

find выдаёт ошибку: "missing argument to -exec".

Неправильно

find . -type f -exec chmod 644 {}
find . -type f -exec chmod 644 {} ;    # нет обратного слеша

Правильно

find . -type f -exec chmod 644 {} \;

Почему

Конструкция -exec требует завершения командой {} (подстановка пути) и обязательного терминатора \;. Точка с запятой ; — специальный символ оболочки, поэтому её нужно экранировать обратным слешем: \;.

Ошибка 5: Различие locate и find при поиске (устаревшая БД)

Симптом

find / -name "myfile.txt" находит файл, а locate myfile.txt — нет (или наоборот — locate находит файл, которого уже нет).

Объяснение

Ключевое отличие: find работает в реальной файловой системе и всегда актуален. locate использует предварительно построенную базу данных — быстро, но может отставать от реальности.

# Если locate не находит файл, который должен быть:
sudo updatedb   # пересоздать базу
locate myfile.txt

Ошибка 6: Бесконечный цикл без exit-условия

Симптом

Скрипт "завис" и не завершается; терминал не отвечает.

Неправильно (забыто условие выхода)

while true
do
    echo "Running..."
    # забыли sleep или условие break
done

Правильно

# С паузой (понятно что выполняется)
while true; do echo "Running..." && sleep 1; done

# С явным условием выхода
counter=0
while true
do
    echo "Counter: $counter"
    ((counter++))
    if [ $counter -ge 5 ]; then break; fi
done

Остановка бесконечного цикла

Ctrl+C    # прервать текущий процесс