Назад | Перейти на главную страницу

У одного лайнера Linux / Sendmail проблемы с большими каталогами

По какой-то причине спамеры нашли способ ретранслировать почту через побочную систему. Эксплойт уже устранен.

Проблема в том, что в моем каталоге / var / spool / mqueue было огромное количество писем (не менее 100000+), которые мне все еще нужно фильтровать. Я остановил sendmail и переместил содержимое каталога mqueue в новое место ...

С тех пор я пытался использовать следующий лайнер в помощь:

for x in `find . -type f -name “qf*” | xargs grep -l "foo" | cut -b3-`; do y=d`echo $x | cut -b2-`; mv $x /root/spammessages; mv $y /root/spammessages/; done

Идея в том, чтобы:

1) проверьте файлы QF на наличие уникального содержимого заголовков, связанных со спамом (foo).

2) Найдите файл-аналог DF

3) Переместите файлы df и qf в изолированную область.

Проблема в том, что запрос выполняется, но не пытается перемещать файлы. Если я бегу сверху, я вижу, что xargs и grep иногда используют некоторые ресурсы, но не более 1% -2%. Более того ... когда я проверяю папку со спам-сообщениями, я не вижу там никаких файлов.

Если я запускаю ту же команду для меньшего набора сообщений, кажется, что все работает нормально. Есть ли здесь какие-то ограничения для файлов Linux? Есть ли способы оптимизировать однострочник?

Спасибо.

-M

Разобьем его на несколько строк

for x in `find . -type f -name "qf*" | xargs grep -l "foo" | cut -b3-`
do 
    y=d`echo $x | cut -b2-`
    mv $x /root/spammessages
    mv $y /root/spammessages/
done
  • Вы всегда должны использовать -print0 с участием find и -0 с участием xargs когда вы передаете имена файлов от одного к другому
  • Использовать $() вместо обратных кавычек для удобочитаемости и возможности вложения и уменьшения необходимости в побегах
  • Всегда заключайте в кавычки имена переменных, которые содержат имена файлов
  • Вызов внешнего (cut) много раз в цикле медленный (я исключил его, так как он все равно не нужен)
  • У вас есть терминальная косая черта в одном каталоге, но нет в другом (согласованность)
  • Вы отсекаете "qf", когда делаете переменную x, но вы не кладете его обратно, когда делаете ход.
  • Вы отсекаете "qf", но не возвращаете "f", когда делаете переменную y (который вы отрезаете от дополнительного символа x)
  • Кроме того, у вас были типографические кавычки (умные или Unicode или как вы хотите их называть) вокруг вашей спецификации файла в find которые могли помешать

Попробуй это:

for x in $(find . -type f -name "qf*" -print0 | xargs -0 grep -l "foo" | cut -b3-)
do 
    mv "qf$x" /root/spammessages/
    mv "df$x" /root/spammessages/
done

Поместите обратно в однострочник:

for x in $(find . -type f -name "qf*" -print0 | xargs -0 grep -l "foo" | cut -b3-); do mv "qf$x" /root/spammessages/; mv "df$x" /root/spammessages/; done

Редактировать:

Вот версия с использованием while цикл, который может работать лучше для очень большого количества файлов:

find . -type f -name "qf*" -print0 | xargs -0 grep -l "foo" | cut -b3- |
while read -r x
do 
    mv "qf$x" /root/spammessages/
    mv "df$x" /root/spammessages/
done

В однострочном виде:

find . -type f -name "qf*" -print0 | xargs -0 grep -l "foo" | cut -b3- | while read -r x; do mv "qf$x" /root/spammessages/; mv "df$x" /root/spammessages/; done

Вариант, использующий подстановку процесса Bash:

while read -r x
do 
    mv "qf$x" /root/spammessages/
    mv "df$x" /root/spammessages/
done < <(find . -type f -name "qf*" -print0 | xargs -0 grep -l "foo" | cut -b3-)

И:

while read -r x; do mv "qf$x" /root/spammessages/; mv "df$x" /root/spammessages/; done < <(find . -type f -name "qf*" -print0 | xargs -0 grep -l "foo" | cut -b3-)