Статьи

Как восстановить полный каталог Unix

Читатель написал мне на этой неделе, что его сценарии bash жалуются на «нехватку памяти»; что он должен сделать? Это не заняло много времени, чтобы заставить его двигаться снова.

Хотя моя коллега Сандра Генри-Стокер обычно освещает эту территорию в своей книге « Unix как второй язык », идеи этого эпизода прекрасно применимы в обычных ситуациях, с которыми сталкиваются разработчики и администраторы Windows, поэтому я думаю, что здесь есть смысл сообщить об этом. Мой корреспондент знал, что он хочет бежать

    find . -type f -exec grep -i -l -H "keyword" '{}' + | xargs rm -rf

но ему не хватало памяти, потому что в его дереве каталогов были миллионы (!) файлов, и, если я его правильно понял, он работал со старым хостом, у которого было только 256 мегабайт основной памяти. Что он должен сделать?

Моя первая мысль:

    INTERMEDIATE_FILE=/tmp/xyz.txt
# Caution: this coding is fragile, in that it mishandles filenames which
# embed blanks. Accommodating those is a story for another day.
find . -type f -exec grep -i -l -H "$keyword" {} \; > $INTERMEDIATE_FILE
for NAME in `cat $INTERMEDIATE_FILE`
do
rm -rf $NAME
done

Это помогло? «Да!», Вернулся отчет — ну, «да и нет». Поскольку я убежден в том, что долгие путешествия начинаются с маленьких шагов, я нашел больше ободрения, чем уныния в ответе. По-видимому, спрашивающему нужно было выполнить несколько волн очистки, и «развертывание» однострочного с помощью $ INTERMEDIATE_FILE помогло в некоторых ситуациях нехватки памяти, но не во всех.

«Один шаг за раз», — подумал я. После нескольких дополнительных переговоров мы сократили его симптомы до «нехватки памяти» с ….

    ls -1 >> $INTERMEDIATE_FILE

и

    find ./ -size -6k -type f >> $INTERMEDIATE_FILE

У меня остались какие-то хитрости?

Конечно; на самом деле, у меня есть история создания этой ситуации для себя. Я часто использую временные файлы для различных автоматизаций тестирования, которые я запускаю, и, если я не разборчив в очистке после тестов, легко найти себя с десятками тысяч файлов, названных, например, / tmp / tmp $ {RANDOM} .журнал. У меня часто было так много таких, что попытка навести порядок в журнале rm / tmp / tmp * делает то, что описал мой спрашивающий: жалуется «нехватка памяти». В таком случае пришло время «съесть слона по одному кусочку за раз», что в данном случае означает что-то вроде

    rm /tmp/tmp*a*.log
rm /tmp/tmp*b*.log
...
rm /tmp/tmp*[g-j]*.log
...
rm /tmp/tmp*[A-H]*.log
...

В английском языке идея состоит в том, чтобы указать подмножество /tmp/tmp*.log, достаточно маленькое, чтобы поместиться в памяти, но достаточно большое, чтобы откусить весь список. Вырезав несколько «кусочков», мы быстро уменьшаем всю коллекцию оставшихся /tmp/tmp*.log до управляемого размера, который может занять более традиционное программирование bash.

Для поиска, гомологический подход будет что-то вроде

    find . -name "*a*" -size -6k -type f >> $INTERMEDIATE_FILE
find . -name "*[bc]*" -size 6k -type f >> $INTERMEDIATE_FILE
...

Конечно, волнение еще не закончилось; такие ситуации, кажется, всегда имеют «свободные концы». В случае моего спрашивающего, у него было много файлов, имена которых включали не-ASCII символы Unicode . У меня также есть множество хитростей для решения этих проблем , включая переход на Tcl для моих сценариев. На этот раз, однако, мы начали с файлов, имена которых легко выразить, обработали их все, а затем, к моему удивлению, определили, что оставшийся остаток был достаточно мал, чтобы спрашивающий мог использовать свои обычные навыки кодирования bash. , Миссия выполнена.

Какой вывод? У меня нет особо отточенного афоризма, чтобы подвести итог тому, что произошло. Тем не менее, я знаю, что многие случаи, которые выглядят как «стопоры шоу» в первый раз, оказываются легко решаемыми для человека с небольшим опытом. Если вы чувствуете застрял, ясно с собой то , что ваши истинные требования, что вы получаете, и кажется, что ограничивает вас. Просить помощи; кто-то другой, с другой точки зрения, может быстро найти способ совместить все элементы вашей проблемы, чтобы найти решение.

Здесь также есть урок о рукоделии, который я еще не знаю, как выразить словами. Часть разницы между «обучением по учебникам» и видом профессиональной подготовки, которую практикуют дизельные механики, врачи, юристы и сантехники, связана с обучением работе с новыми ситуациями. Это включает в себя тщательное обучение основам с последующим воздействием прогрессивно более сложных вариаций. Если rm * не дает вам того, что вы хотите, разбейте * часть на части, достаточно маленькие для обработки.