can anybody give me a solution to truncate all logfile in /var/log/
directory?
and a question just for knowledge, is it a good idea or not?
#!/bin/bash
LOGDIR="/var/log"
for logfile in $(ls $LOGDIR/*log)
do
truncate -s 0 $logfile
done
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It only takes a minute to sign up.
Sign up to join this communitytry this:
truncate -s 0 /var/log/*log
EDIT:
if you want to do this more than once you should use logrotate
to handle your logs. Usually it's installed in ubuntu. Have a look at man logrotate
(or if you do not have it installed look at the online manpage or install it with sudo apt-get install logrotate
)
from the manpage:
logrotate is designed to ease administration of systems that generate large numbers of log files. It allows automatic rotation, compression, removal, and mailing of log files. Each log file may be handled daily, weekly, monthly, or when it grows too large.
If you want to clear all your log files, not just those in the first-level log folder, you could use:
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
Noting that if you already have logrotate
running, you'll need to clear out the rotated .gz
logs as well:
find /var/log -type f -name '*.[0-99].gz' -exec rm {} +
A valid use for this could be building a VM appliance container for distribution, for example.
You should not need to do this as part of routine maintenance: as D-E-N quite correctly suggested, use logrotate
for that.
As follow up to @D-E-N answer
This will find all log files in /var/log
and truncate them to 0 bytes.
find /var/log -type f -iname '*.log' -print0 | xargs -0 truncate -s0
*.log*
instead but I'm not sure if it's 100% safe, so I haven't included it in the answer. Because there are files like dovecot.log-20180930
and dovecot.log-20180923.gz
.
There's couple methods to fully truncating a file, generally applicable to most POSIX-compliant OS. Most common that you'll see with shell scripting is something like true > file.txt
or : > file.txt
( and in case of bash
shell, >
redirection alone is sufficient ). That's due to the way how >
opens files via open()
or openat()
syscall with O_WRONLY|O_CREAT|O_TRUNC
flags - that reads write-only OR create if filename doesn't exist, OR truncate existing filename.
With that in mind, we can implement something like that in C ourselves:
#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;
}
Name the file that stores this code as trunc.c
and compile that with gcc trunc.c -o trunc
, and you have yourself a small utility that will truncate a filename argument it's provided as in trunc ./foobar.txt
. Of course, this code doesn't do other checks, it only truncates first positional parameter. I'll leave it up to the readers to figure out how to deal with more than one positional parameter. On side note, there is truncate()
syscall which we could use as well, and truncate a file to variable length.
Now, if you are not a fan of C, Python might be easier for you. open()
command operates on the same principle in Python - opening file for writing and truncating if filename exists. Thus we can do
python -c 'import sys;open(sys.argv[1],"w").close()' passwd.copy
As for finding all .log
files, that's been covered in other answers already - use *
glob or extended glob in bash
. There's also find -type f -name "*.log"
, which has -exec
flag for running commands (in this particular case sh -c ''
to take advantage of >
because >
is a shell operator and not an external executable). Thus you can do
find /var/log -type f -name "*.log" -exec sh -c 'true > "$1"' sh {} \;
It's also worth noting that log files in directory such as /var/log
often are rotated by logrotate service, so there will be filenames such as /var/log/service.log
, /var/log/service.log.1
, etc , so you may want to use *.log.[1-9]
pattern instead
Among other things, we can copy /dev/null
into the desired file. Oddly enough, even though /dev/null
is a special character device type of file, when you copy that elsewhere the result is empty regular file, at least with GNU cp
. Thus we can do
cp /dev/null foo.txt
or
dd if=/dev/null of=foo.txt
Other suggested reading:
It is good practice to rotate the logs in /var/logs to rotate with logrotate functionality but not whenever we wish to do. System logs will be printed her and they will be handy to debug any failures.
If it is a requirement not to use logrotate, then options can be explored. Though truncate is easy option in few flavors of unix system this command is not available readily, need to be installed.If not allowed to install the new command then below loop can be used.
for logfile $(ls /path/*.log)
do
cat /dev/null > $logfile
done
for logfile in /path/*.log
instead.
/var/log
is where the system puts messages you might need later. Ubuntu has encountered the problem before. Readman 8 logrotate;man logrotate.conf
.