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:
-execrunsrmon 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 singlermcommand, 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.-tinmvspecifies 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
*.logexpands 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
findorxargsinstead 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
*.extinto a list of filenames that exceeds the system’s argument length limit. - Example:
rm *.logmight expand torm file1.log file2.log ... file100000.log, which exceedsARG_MAX.
Final Tips:
- Test commands with
echofirst (e.g.,find ... -exec echo rm {} \;). - Use
rsyncfor large file transfers:
rsync -a --remove-source-files /source/ /destination/