我想使用cron工作,每三天一次将清理并排序maillog。
我的工作看起来像
/bin/sed -i /status=/!d /var/log/maillog |
(/bin/grep "status=bounced" /var/log/maillog | /bin/grep -E -o --color "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" | /bin/sort -u >> /root/unsent.log) |
(/bin/grep "status=deferred" /var/log/maillog | /bin/grep -E -o --color "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" | /bin/sort -u >> /root/deferred.log) |
(/bin/grep "status=sent" /var/log/maillog | /bin/grep -E -o --color "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" | /bin/sort -u >> /root/sent.log) |
/bin/sed -i "/status=/d" /var/log/maillog
工作正常并且做了3步:
完成这项工作后,我的maillog完全干净并分为3个日志。
但Postfix不想将下一条记录写入maillog。
我删除sed命令,Postfix写下接下来的记录很好。
为什么sed命令会在执行cron job后阻止maillog?
答案 0 :(得分:1)
sed -i
将取消它修改的文件的链接,因此syslog / postfix将继续写入不存在的文件。
来自http://en.wikipedia.org/wiki/Sed:
注意:“sed -i”用新的文件覆盖原始文件,打破原文可能有的任何链接
使用logrotate
或savelog
之类的工具将日志文件旋转到一定位置后处理日志文件更为常见,这样syslog就可以继续不间断地写入。
如果必须编辑/var/log/maillog
,可以在cron作业结束时添加一行,以便在完成后重新加载syslog。请注意,如果执行此操作,您可以在脚本运行时丢失写入文件的日志行。该命令取决于您运行的分发/操作系统。在使用rsyslog的ubuntu上,它将是reload rsyslog >/dev/null 2>&1
。
答案 1 :(得分:0)
我重新格式化了原始代码,以突出显示您添加的管道
/bin/sed -i /status=/!d /var/log/maillog \
| (/bin/grep "status=bounced" /var/log/maillog \
| /bin/grep -E -o --color "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" \
| /bin/sort -u >> /root/unsent.log\
) \
| (/bin/grep "status=deferred" /var/log/maillog \
| /bin/grep -E -o --color "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" \
| /bin/sort -u >> /root/deferred.log\
) \
| (/bin/grep "status=sent" /var/log/maillog \
| /bin/grep -E -o --color "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" \
| /bin/sort -u >> /root/sent.log \
) \
| /bin/sed -i "/status=/d" /var/log/maillog
正如@alberge所指出的那样,你很可能会丢失同一文件中所有这些sed -i
处理的日志消息。
我提出了一种不同的方法:
我会将maillog移动到日期文件名,(这里的假设是Postfix会创建一个新文件,其标题名称'喜欢'使用(/ var / log / maillog)。
然后你真正的目标似乎是将各种类别的消息提取到单独命名的文件,即unsent.log,deferred.log,sent.log然后你丢弃任何不包含字符串{{0}的行。 1}}(尽管你先这样做)。
这是我的备用(请阅读整条信息,不要立即复制/粘贴/执行!)。
status=
要测试此代码是否有效,请将第二行( logDate=$(/bin/date +%Y%m%d.%H%M%S)
/bin/mv /var/log/maillog /var/log/maillog.${logDate}
/bin/grep "status=bounced" /var/log/maillog.${logDate} \
| /bin/grep -E -o --color "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" \
| /bin/sort -u \
>> /root/unsent.log.${logDate}
/bin/grep "status=deferred" /var/log/maillog.${logDate} \
| /bin/grep -E -o --color "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" \
| /bin/sort -u \
>> /root/deferred.log.${logDate}
/bin/grep "status=sent" \
| /bin/grep -E -o --color "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" \
| /bin/sort -u \
>> /root/sent.log.${logDate}
)替换为
/bin/mv ....
将其复制/粘贴到终端窗口中,确认已正确复制 /bin/cp /var/log/maillog /var/log/maillog.${logDate}
,然后一次复制/粘贴每个部分1,并检查每个部分中是否创建了预期输出{{1 logfiles。
(如果您收到任何这些块的错误消息,请确保在每个连续行上的最后一个'\'字符后面没有空格/制表符字符。或者您可以将这3个管道中的每一个折叠回一个行,删除'\'字符。
(注意,要创建每个/var/log/maillog.${logDate}
日志文件,我不会通过子进程包围的管道使用任何连接部分。但是,在其他情况下,我会使用这种技术来处理高级问题,所以不要把技术扔掉,只要在真正需要的时候使用它; - )!
确认所有这些工作正常后,然后扩展脚本以进行最后的清理:
/root
我已将/root
添加到您的每个输出文件中,但是当我看到您正在使用/bin/rm /var/log/maillog.${logDate}
时,您可能希望将该“扩展名”删除到您的子日志文件名称(未发送)。 log,deferred.log,sent.log)让这些文件自然增长。在任何一种情况下,您都必须在某个时刻回头并确定您希望保留这些数据的时间,并制定计划和方法,以便在这些日志文件无效时如何清理它们。我想有人提到${logDate}
包。您可能希望将其视为长期解决方案。
此解决方案避免了大量额外进程的创建,并且(大部分)消除了丢失日志记录的可能性。如果Postfix在移动文件时以相同的瞬间写入日志文件,我认为您可能会丢失全部或部分记录。但是你的解决方案会遇到类似的问题以及更多的机会。
如果我误解了您的设计意图,请使用嵌套的sort -u >>
子流程,抱歉!请考虑更新您的帖子,以包括您使用该技术的原因。
我希望这会有所帮助。