How to Use `find` and `xargs` Together to Delete Old Log Files Without Accidentally Removing Your Home Folder

The “find + xargs” combo is a classic for cleaning up old logs, but it can be a double‑edged sword if you’re not careful.

Below is a step‑by‑step guide that shows how to target only the log files you want to delete, keep your home folder safe, and understand the trade‑offs of the different options you’ll see.


Why find and xargs instead of rm -r?

find is the Swiss‑army knife of file searching: you can filter by name, age, size, permissions, and more.
xargs takes the list that find spits out and feeds it to another command, usually rm.
The pair is efficient because it processes files in batches, sidestepping the “argument list too long” error that can bite you if you try to delete thousands of files with a single rm.


1. Identify the log files you actually want to delete

Before you start deleting, run a dry‑run to see what will be affected.
Assume your logs live under /var/log and you want to delete files older than 30 days that end in .log.

find /var/log -type f -name '*.log' -mtime +30 -print
  • -type f – only regular files
  • -name '*.log' – match the pattern
  • -mtime +30 – modified more than 30 days ago
  • -print – show the full path

If the output looks correct, you’re ready to delete.


2. Safely delete with xargs

The most common pattern is:

find /var/log -type f -name '*.log' -mtime +30 -print0 | xargs -0 rm -f

What each part does

Component Purpose
-print0 Outputs filenames followed by a null byte, which handles spaces and newlines in filenames.
xargs -0 Reads null‑terminated strings, matching -print0.
rm -f Force delete without prompting.

Why -print0 / -0?

Log files rarely contain spaces, but if you ever have a custom log name like app log 2024-11-01.log, the null‑byte approach prevents mis‑parsing.


3. Avoid touching your home directory

A common mistake is to run find / -type f -mtime +30 -name '*.log' -print0 | xargs -0 rm -f from the root.
That will delete every log file on the system, including those in /home/youruser, which might be application logs you actually need.

Two safeguards

  1. Explicit path – always specify the directory you want to clean, e.g., /var/log.
    Avoid find / unless you’re absolutely sure.

  2. Use -path to exclude – if you must search the whole tree, exclude /home:

    find / -type f -name '*.log' -mtime +30 \
         ! -path '/home/*' -print0 | xargs -0 rm -f
    

    The ! -path '/home/*' clause tells find to skip everything under /home.


4. Test with -exec before xargs

find can run a command directly on each file.
This is safer for a first run because you can see the exact command that will execute.

find /var/log -type f -name '*.log' -mtime +30 -exec rm -i {} \;
  • -exec rm -i {} \; – prompts before each delete.
  • If you’re comfortable, replace -i with -f to skip prompts.

5. Batch size matters

When you have thousands of files, xargs will by default group them into batches of 256 or so.
You can control the batch size with -n:

find /var/log -type f -name '*.log' -mtime +30 -print0 | xargs -0 -n 100 rm -f
  • -n 100 – pass at most 100 filenames to rm at a time.
    Smaller batches reduce the risk of hitting the maximum argument length, but increase the number of rm invocations.

6. Using -delete instead of xargs

Modern find supports the -delete action, which removes files directly:

find /var/log -type f -name '*.log' -mtime +30 -delete

Pros:

  • No need for xargs.
  • Simpler syntax.

Cons:

  • -delete stops processing the current directory if it fails (e.g., due to permissions).
  • Some older find versions (e.g., on very old Debian releases) may not support -delete.

If you’re on a recent distribution (Debian 12, Ubuntu 24.04, Fedora 40, etc.), -delete is usually the cleanest choice.


7. Logging the deletion

It’s a good practice to keep a record of what you delete, especially on a production server.

find /var/log -type f -name '*.log' -mtime +30 -print0 | \
  tee /tmp/old_logs_to_remove.txt | \
  xargs -0 -r rm -f
  • tee writes the list to /tmp/old_logs_to_remove.txt while passing it through to xargs.
  • -r (or --no-run-if-empty) prevents xargs from running rm if the list is empty.

8. Common pitfalls and how to avoid them

Pitfall Symptom Fix
Accidentally deleting /home logs rm: cannot remove '/home/...': Permission denied or files vanish Use explicit path or ! -path '/home/*'
Files with spaces or newlines rm: cannot remove 'app log 2024-11-01.log': No such file or directory Use -print0 / -0
Running as root without checks System crash or data loss Test with -print or -exec rm -i first
xargs ignoring empty input rm: missing operand Add -r or --no-run-if-empty
Over‑aggressive age filter Deleting recent logs Verify -mtime +30 vs -mtime -30

9. Automating with a cron job

If you routinely clean logs, schedule a daily job:

# /etc/cron.d/clean-logs
15 2 * * * root find /var/log -type f -name '*.log' -mtime +30 -delete
  • Runs at 02:15 every day.
  • root ensures it has permission to delete system logs.
  • The -delete action is safe and concise.

Always test the cron command manually before adding it to the crontab.


10. Security considerations

  • Least privilege – run the deletion as a user that only has access to the target directory.
    For /var/log, the root user is typical, but if you’re cleaning user‑specific logs, use that user’s account.

  • Audit trail – keep a log of deletions (see section 7).
    On a multi‑user system, this helps trace accidental or malicious deletions.

  • Avoid sudo rm -rf / – a typo can wipe the whole system.
    Use sudo -l to review allowed commands and consider sudo -v before running the script.


11. When xargs is not enough

If you need more complex filtering (e.g., delete logs only from a specific service), combine find with grep:

find /var/log -type f -name '*.log' -mtime +30 -print0 | \
  xargs -0 -I{} sh -c 'basename "{}" | grep -q "^nginx" && rm -f "{}"'

This deletes only files whose base name starts with nginx.
The -I{} placeholder lets you run a shell command per file.


12. Quick reference cheat sheet

Command What it does
find /var/log -type f -name '*.log' -mtime +30 -print List old logs
find /var/log -type f -name '*.log' -mtime +30 -delete Delete them (no xargs)
`find /var/log -type f -name ‘*.log’ -mtime +30 -print0 xargs -0 rm -f`
`find /var/log -type f -name ‘*.log’ -mtime +30 -print0 tee /tmp/old_logs.txt
`find / -type f -name ‘.log’ -mtime +30 ! -path ‘/home/’ -print0 xargs -0 rm -f`

13. Resources

  • GNU find manual – -delete
  • Linux man page for xargs
  • Debian Wiki – Log Rotation – for complementary log‑rotation strategies

See also