Fixing "Argument list too long" — When rm * and Similar Commands Fail

Fixing "Argument list too long" — When rm * and Similar Commands Fail

What This Article Covers

  • Why rm * and cp * dest/ fail with "Argument list too long"
  • How to process large numbers of files safely using find + xargs and find -delete
  • How to handle filenames with spaces or special characters

Quick fix

# Replacement for rm * — safest approach
find . -maxdepth 1 -name "*.log" -type f -delete

# Or via xargs
find . -maxdepth 1 -name "*.log" -print0 | xargs -0 rm

Why Does "Argument list too long" Happen?

When you run rm *, the shell (not rm) expands the wildcard first. With tens of thousands of files, the resulting argument list exceeds the kernel limit ARG_MAX, and the kernel returns an E2BIG error.

$ rm *.log
-bash: /bin/rm: Argument list too long

Check your system's ARG_MAX:

$ getconf ARG_MAX
2097152
2097152

The typical value on Linux is 2 MB (2,097,152 bytes). Once the total length of all expanded arguments exceeds this, the command fails.

This error affects any command that uses wildcards: ls *.log, cp *.log dest/, cat *.txt, chmod 644 *.php, and so on.

find processes files one at a time and never builds a full argument list for exec(), which is why it bypasses this limit entirely.

Fix with find -delete

For deletion, find -delete is the simplest and safest option — no xargs required.

find . -maxdepth 1 -name "*.log" -type f -delete
  • -maxdepth 1: current directory only (equivalent scope to rm *)
  • -type f: files only (prevents accidental directory deletion)
  • -delete: delete each match

To include subdirectories, remove -maxdepth:

find /path/to/dir -name "*.log" -type f -delete

Before deleting, verify what will be removed:

# Preview matches and count
find . -maxdepth 1 -name "*.log" -type f
find . -maxdepth 1 -name "*.log" -type f | wc -l

Fix with find + xargs

A general-purpose pattern that works with any command, not just rm.

Basic pattern

find . -maxdepth 1 -name "*.log" | xargs rm

xargs automatically batches arguments to stay within ARG_MAX.

Filenames with spaces or special characters

Default xargs splits on whitespace, which breaks filenames containing spaces. Use -print0 with xargs -0 (NUL-delimited) for full safety:

find . -maxdepth 1 -name "*.log" -print0 | xargs -0 rm

Using -print0 | xargs -0 as the default is the safest habit.

Parallel execution for speed

find . -name "*.log" -print0 | xargs -0 -P4 rm

-P4 runs 4 processes in parallel. Useful when deleting a very large number of files.

Fix for cp / mv

The same E2BIG error appears with cp * dest/ and mv * dest/.

# cp
find . -maxdepth 1 -name "*.log" -print0 | xargs -0 -I{} cp {} /dest/

# mv
find . -maxdepth 1 -name "*.log" -print0 | xargs -0 -I{} mv {} /dest/

-I{} substitutes each path into {}.

You can also use -exec:

find . -maxdepth 1 -name "*.log" -exec cp {} /dest/ \;

-exec spawns one process per file, so xargs is faster for large file counts.

Fix with a Shell Loop

A simple alternative when find is unavailable, or when you need to review each file before acting.

for f in *.log; do
    rm "$f"
done

The shell invokes rm once per file, so ARG_MAX is never reached.

Always quote "$f". Without the quotes, filenames containing spaces will cause the loop to break.

Summary

Approach Example Best for
find -delete find . -name "*.log" -type f -delete Deletion only (simplest)
find | xargs rm find . -name "*.log" | xargs rm Standard deletion
-print0 | xargs -0 find . -name "*.log" -print0 | xargs -0 rm Special-char filenames
Shell loop for f in *.log; do rm "$f"; done Step-by-step review
-exec find . -name "*.log" -exec cp {} /dest/ \; Non-delete operations

Decision flow

  1. Deleting files → find -delete
  2. Copying or moving → find ... -print0 | xargs -0 command
  3. Review each file as you go → shell loop

Next Reading