To resolve the “Argument list too long” error in Linux/Unix when using commands like rm
, cp
, or mv
, you need to bypass the shell’s argument limit. This error occurs because the shell expands wildcards (e.g., *
) into a list of files that exceeds the system’s maximum allowed argument length (ARG_MAX
). Below are detailed solutions with examples:
1. Use find
with -exec
or -delete
The find
command processes files in batches, avoiding the argument limit.
Example 1: Delete files matching a pattern
# Delete all .log files recursively
find . -type f -name "*.log" -exec rm {} \;
- Explanation:
-exec
runsrm
on each file individually (safe but slow for large datasets).
Optimized Version (faster)
find . -type f -name "*.log" -exec rm {} +
- Explanation:
{} +
groups multiple files into a singlerm
command, reducing overhead.
Use -delete
(faster for deletion)
find . -type f -name "*.log" -delete
2. Use xargs
to Handle Batches
xargs
splits input into chunks that fit within ARG_MAX
.
Example 2: Move files to a directory
find . -type f -name "*.txt" -print0 | xargs -0 mv -t /target/directory
- Explanation:
-print0
(find) and-0
(xargs) handle filenames with spaces.-t
inmv
specifies the target directory first.
Example 3: Copy files
find . -type f -name "*.jpg" -print0 | xargs -0 cp -t /target/directory
3. Use a for
Loop (Caution: Shell Compatibility)
For small to moderate numbers of files, use a loop with pattern matching.
Example 4: Remove files in batches
for file in *.log; do rm "$file"; done
- Note: This may still fail if
*.log
expands beyondARG_MAX
.
4. Delete Files by Directory (No Wildcard)
If all files are in a single directory, use a subshell to avoid wildcard expansion.
Example 5: Remove all files in a directory
cd /path/to/directory && rm -f *
- Note: This works if the directory itself does not exceed
ARG_MAX
.
5. Increase System Limits (Advanced)
Adjust the kernel’s maximum argument length (not recommended for most users).
Check current ARG_MAX:
getconf ARG_MAX # Typically 2097152 bytes (2MB) on modern systems
Temporarily increase stack size:
ulimit -s 65536 # Set stack size to 64MB (reverts after session)
Examples Summary
Command | Use Case |
---|---|
find . -name "*.log" -delete | Fast deletion without wildcard expansion |
find ... -exec rm {} + | Batch deletion with find |
xargs -0 mv -t /target | Move files with spaces in names |
rsync + rm | Copy-then-delete large datasets |
Key Fixes:
- Avoid Wildcard Expansion: Use
find
orxargs
instead of*
. - Handle Filenames with Spaces: Use
-print0
(find) and-0
(xargs). - Batch Processing: Group files into chunks with
{} +
orxargs
.
Why This Error Occurs:
- The shell expands
*.ext
into a list of filenames that exceeds the system’s argument length limit. - Example:
rm *.log
might expand torm file1.log file2.log ... file100000.log
, which exceedsARG_MAX
.
Final Tips:
- Test commands with
echo
first (e.g.,find ... -exec echo rm {} \;
). - Use
rsync
for large file transfers:
rsync -a --remove-source-files /source/ /destination/