"Утечка" памяти 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
Другие вопросы по тегам