0

I recently came across this page that indicates how to empty a file. How can I do it for all files in a given subfolder ?

For instance, by using > file.log to empty a file ?

I basically want to create a VM instance image, and I'd like to clear existing log files so when the template is used it starts fresh without lingering data

  • I don't understand the downvotes... is it because what I'm trying to do is so trivial for you guys ? This is not nice... at least explain what is missing in my question. Furthermore we've seen several corner cases in the answers below so does my question not make sense ? Seriously you even have a "New Contributor" banner under my flair that tells you to. – Cyril Duchon-Doris Sep 9 '18 at 15:36
3

With

for i in /var/log/*; do
    > "$i"
done

If you want to avoid the error messages for the directories, include a test.

for i in /var/log/*; do
    test -f "$i" && > "$i"
done
  • I'm not sure by what you meant by "error messages for the directories", but If I run your original command in an empty directory it actually creates a file named * – Cyril Duchon-Doris Sep 9 '18 at 13:42
  • 1
    Yes, if you run it in an empty directory it actually creates a file named *, but then obviously there is no need for it. It is also possible to include a test against the directory being empty, and in fact the second version doesn't create a file *. What I meant is if the directory is not empty, but contains sub directories, you will get an error message for each sub directory with the first command. You can ignore that message, but if you use a script, then use the second command. – RalfFriedl Sep 9 '18 at 13:46
  • shopt -s nullglob will help the empty-directory scenario – Jeff Schaller Sep 9 '18 at 15:22
  • Hey, how can I run this command with sudo ? – Cyril Duchon-Doris Sep 9 '18 at 16:14
  • You can either place the commands in a file and run that file, or run it as one command: sudo sh -c 'for i in /var/log/*; do test -f "$i" && > "$i"; done. – RalfFriedl Sep 9 '18 at 16:17
2

Another option, in a single command, would be truncate:

truncate -s /var/log/*

The above will emit errors for any subdirectories of /var/log, though:

truncate: cannot open '/var/log/subdir' for writing: Is a directory

... which you can silence by dropping stderr:

truncate -s /var/log/* 2>/dev/null

If there are no files or directories, then you have to beware of the current nullglob shell option. By default, it is turned off:

$ shopt nullglob
nullglob        off

... which will leave the * unexpanded, and thus truncate will create a file named *. You can avoid this in two ways:

  1. set nullglob: shopt -s nullglob before running truncate. You will then (if you haven't dropped stderr) see an error:

    truncate: missing file operand

  2. tell truncate not to create missing files: truncate --no-create -s 0 /var/log/*

  • Hey thanks for the detailed explanation, I did not know about the nullglob option, this deserves an upvote ! – Cyril Duchon-Doris Sep 9 '18 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.