Linux / Sendmail 单行程序处理大型目录时遇到问题

Linux / Sendmail 单行程序处理大型目录时遇到问题

无论出于什么原因,垃圾邮件发送者都找到了通过侧系统转发邮件的方法。该漏洞已得到解决。

问题是我的 /var/spool/mqueue 目录中有大量电子邮件(至少 100,000 封以上),我仍需要过滤。我停止了 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 文件移至隔离区域。

问题是查询正在运行,但似乎没有移动任何文件。如果我运行 top,我会看到 xargs 和 grep 偶尔会使用一些资源,但不会超过 1%-2%。此外……当我检查 spammessages 文件夹时,我没有在那里看到任何文件。

如果我在较小的消息子集上运行相同的命令,它似乎工作正常。这里有一些 Linux 文件限制吗?有没有办法优化单行命令?

谢谢。

-M

答案1

让我们把它分成多行

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
  • 当你将文件名从一个管道传输到另一个管道时,应始终使用-print0withfind-0withxargs
  • 使用$()反引号可以提高可读性,并且能够嵌套并减少转义的需要
  • 始终引用保存文件名的变量名
  • 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-)

相关内容