我正在尝试使用cron脚本管理我的日志文件大小。我基本上想要每晚删除除日志文件的最后2000行以外的所有内容。我正在尝试运行此命令,但它似乎正在清空整个文件而不是按照我的意愿执行:
tail -2000 logfile.txt> LOGFILE.TXT
有谁知道为什么这不起作用和/或如何完成我想要的东西?谢谢!
答案 0 :(得分:14)
在tail
开始阅读之前,您正在覆盖该文件。 shell通过首先清除文件来处理>
重定向运算符。然后它运行tail
,无法读取数据。
您可以使用临时文件解决此问题:
tail -2000 logfile.txt >logfile.tmp
mv logfile.tmp logfile.txt
答案 1 :(得分:10)
您可能希望使用logrotate
来寻找更强大的解决方案,而不是使用自己的cron文件执行此操作。您可以旋转日志,控制它们保留多长时间,通过电子邮件发送,压缩旧日志,然后根据需要运行脚本。
请参见手册页here
或者从命令行输入man logrotate
在/etc/logrotate.d/目录中创建一个新的logrotate文件。这是一个例子:
/var/logs/myapp/logfile.txt {
# keep the 5 latest rotations of the log
rotate 5
# rotate once the file is bigger than 2k
size 2k
# don't error if the file isn't there
missingok
# compress rotated (old) log files
compress
# set ownership and permissions on the new log file
create 0640 myuser myuser
}
答案 2 :(得分:10)
如果进程保持日志文件打开,则接受的解决方案存在问题;你基本上需要重用i-node。 Mmrobins的反应很好, logrotate 应该做对了。
要使用尾,您可以执行某些操作(类似于Pantonza& Greg的想法),但通过原位截断原始文件来保留原始文件:
tail -2000 logfile.txt >logfile.tmp
cat logfile.tmp > logfile.txt
rm logfile.tmp
要避免临时文件,您可以读入变量,然后将其填充:
bash -c 'X=$(tail -2000 logfile.txt);echo "$X">logfile.txt'
在所有情况下,截断与附加到文件的进程之间可能存在竞争条件。不确定 logrotate 是否处理了这个问题, tail 解决方案都没有。
答案 3 :(得分:4)
这是另一个解决方案,不处理tmp文件:
echo "`tail -2000 logfile.txt`" > logfile.txt
答案 4 :(得分:1)
Greg Hewgill是对的,logfile.txt在tail可以工作之前被截断。
尝试:
tail -2000 logfile.txt > logfile2.txt; rm -f logfile.txt; mv logfile2.txt logfile.txt
答案 5 :(得分:1)
如果您是vim用户,则另一个选项是使用vi
代替tail
,直接对该文件进行操作:
vi "+execute \"normal! G2000kO\<esc>dgg\"" "+w" "+q" logfile.txt
字符串G2000kO\<esc>dgg
只是用于使用vi执行此操作的键盘输入(必须转义转义按钮)。它使用非常直观,涵盖了大量的用例。
vi还可以处理大型(10+ GB)文本文件,甚至不会减慢速度,因此这种方法非常强大。