如何截断所有日志文件?


18

有人可以给我一个解决方案,以截断/var/log/目录中的所有日志文件吗?

还有一个只是为了知识的问题,这是一个好主意吗?

#!/bin/bash
LOGDIR="/var/log"
for logfile in $(ls $LOGDIR/*log)
do
  truncate -s 0 $logfile
done

1
这不是一个好主意- /var/log系统在哪里放置您以后可能需要的消息。Ubuntu之前曾遇到过此问题。阅读man 8 logrotate;man logrotate.conf
waltinator

Answers:


34

尝试这个:

truncate -s 0 /var/log/*log

编辑:

如果您想多次执行此操作,则应使用它logrotate来处理日志。通常它安装在ubuntu中。看一看man logrotate(或者如果您没有安装它,请看联机手册或使用来安装它sudo apt-get install logrotate

从联机帮助页:

logrotate旨在简化对生成大量日志文件的系统的管理。它允许自动旋转,压缩,删除和邮寄日志文件。每个日志文件都可以每天,每周,每月或当它变得太大时进行处理。


您也可以使用echo“”> * log清空它们
Astm

10

如果要清除所有日志文件,而不仅是第一级日志文件夹中的日志文件,可以使用:

shopt -s globstar                  # if needed
truncate -s 0 /var/log/*.log       # first-level logs
truncate -s 0 /var/log/**/*.log    # nested folders, like /var/log/nginx/access.log

请注意,如果您已经在logrotate运行,则还需要清除轮换的.gz日志:

find /var/log -type f -name '*.[0-99].gz' -exec rm {} +

例如,对此的有效用途可能是构建VM设备容器以进行分发。

你应该不会需要做到这一点作为日常维护的一部分:作为DEM非常正确建议,用logrotate了点。


1

作为@DEN的跟进答案的

这将找到所有日志文件,/var/log并将其截断为0个字节。

find /var/log -type f -iname '*.log' -print0 | xargs -0 truncate -s0

1
我会*.log*改用它,但是我不确定它是否100%安全,所以我没有将其包含在答案中。因为有类似dovecot.log-20180930和的文件dovecot.log-20180923.gz
卢卡

0

有两种方法可以完全截断文件,通常适用于大多数POSIX兼容操作系统。您会在shell脚本中看到的最常见的东西是true > file.txt: > file.txt(并且在bashshell的情况下,>仅重定向就足够了)。这是由于如何>通过带有标志的通过open()openat()syscall 打开文件的方式O_WRONLY|O_CREAT|O_TRUNC-读取只读或在文件名不存在时创建,或截断现有文件名。

考虑到这一点,我们可以在C自己中实现类似的内容:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char **argv){
    if (argc == 2){
        int fd = open(argv[1],O_TRUNC);
        close(fd);
    }

    return 0;
}

将存储该代码的文件命名为,trunc.c然后使用进行编译,gcc trunc.c -o trunc您将拥有一个小的实用程序,该实用程序将截断它在中提供的文件名参数trunc ./foobar.txt。当然,此代码不会进行其他检查,它只会截断第一个位置参数。我将由读者自己决定如何处理多个位置参数。附带说明一下,truncate()我们也可以使用syscall,并将文件截断为可变长度。

现在,如果您不喜欢C,Python对您来说可能会更容易。open()命令在Python中的操作原理相同-打开文件以写入文件并在文件名存在时截断。这样我们可以做

python -c 'import sys;open(sys.argv[1],"w").close()' passwd.copy 

至于查找所有.log文件,已经在其他答案中进行了介绍-在中使用*glob或扩展glob bash。还有find -type f -name "*.log",它具有-exec用于运行命令的标志(在这种特殊情况下sh -c ''可以利用,>因为>它是shell运算符,而不是外部可执行文件)。这样你就可以做

find /var/log -type f -name "*.log" -exec sh -c 'true > "$1"' sh {} \;

另外值得一提的在目录中的日志文件,如/var/log经常被logrotate的服务旋转,所以会出现文件名,例如/var/log/service.log/var/log/service.log.1等等,所以你可能想使用*.log.[1-9]模式,而不是


除其他外,我们可以复制/dev/null到所需文件中。奇怪的是,即使/dev/null是特殊字符设备类型的文件,当您将其复制到其他地方时,结果至少是使用GNU的情况下还是空的常规文件cp。这样我们可以做

cp /dev/null foo.txt

要么

dd if=/dev/null of=foo.txt

其他建议阅读:


0

优良作法是将/ var / logs中的日志旋转为使用logrotate功能进行旋转,但并非每次我们希望这样做时。系统日志将被打印出来,并且可以方便地调试任何故障。

如果要求不使用logrotate,则可以探索选项。尽管在少数几种unix系统中,truncate是很容易的选择,但是此命令不容易使用,需要安装。如果不允许安装新命令,则可以使用下面的循环。

for logfile $(ls /path/*.log)
do 
  cat /dev/null > $logfile
done

Bash陷阱#1不要那样写循环。使用for logfile in /path/*.log代替。
PerlDuck
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.