"Утечка" памяти Bash при повторном использовании каталогов
В настоящее время я пытаюсь написать скрипт, который выполняет некоторую постобработку после rsync --max-size=4000000000
выполнил свою работу, чтобы обеспечить полное резервное копирование в FAT32 (единственная файловая система, которая является r/w на всех Windows/Mac/*nix)
Я пишу на bash для Mac OS X и Linux; в настоящее время тестирование на OS X. Код здесь
https://github.com/taikedz/fullsync32/blob/master/fullsync32
Скрипт рекурсивно находит каталоги
- файлы с ветвью ресурса (свойство HFS)
- файлы размером более 4 ГБ
и при обнаружении таких файлов либо обрабатывает их через tar -cz
или же split
при необходимости, прежде чем копировать их.
Я использую рекурсию вместо find
Утилита из-за теста на наличие разветвления ресурса в файле: включает проверку размера специального файла. Скажем, у вас есть файл foo.txt; его ветку ресурса можно найти, посмотрев на ls -l foo.txt/..namedfork/rsrc
и проверка длины не равна нулю.
Основная структура
recurse() { pushd "$1" для узла в *; делать if [ -d "$NODE" ]; затем рекурс "$ NODE" Продолжить фи # (здесь обрабатываются файлы с вызовами split, tar и md5) сделанный POPD } recurse./target/directory
проблема
Я проверил это на фоне своих резервных копий на днях и оставил работать несколько часов. Когда я вернулся, я обнаружил, что мои запасные 11 ГБ ОЗУ были израсходованы, и это было ~248 МБ в обмен...
Я искал в Google проблемы с утечкой памяти bash при рекурсии, и, за исключением нескольких небрежно отвеченных сообщений на форуме, не нашел много...
Другой результат добавления (который является специфическим для Mac) заключается в том, что "Неактивная память" остается неактивной, а система работает медленно... Требуется перезагрузка.
Вопросы
- Является ли такая потенциально глубокая рекурсия с bash самой плохой идеей?
- Есть ли в этой ситуации гениальный способ повторения, а не повторения?
- или я все равно пойду по этому поводу?
Ваши отзывы очень ценятся!
1 ответ
Является ли такая потенциально глубокая рекурсия с bash самой плохой идеей?
Bash не предназначен для рекурсии, но не имеет проблем с возвратом на несколько тысяч уровней, которых более чем достаточно для рекурсии через файловую систему.
Тем не менее, Bash, как и все языки, не в состоянии выполнить нехвостовую рекурсию на бесконечную глубину, как вы рискуете, отказавшись от find
проверенный цикл обнаружения.
Есть ли в этой ситуации гениальный способ повторения, а не повторения?
Вы можете перебирать find
выход:
find "$1" -print0 | while IFS= read -d '' -r filename
do
echo "Operating on $filename"
done
как использовать найти для выполнения теста
Вы можете запустить произвольные внешние тесты с -exec
Ок, тут вспоминаем bash:
find / -exec bash -c '[[ -s "$1/..namedfork/rsrc" ]]' _ {} \; -print