What the message looks like
$ rm /var/spool/app/cache/*.tmp
-bash: /usr/bin/rm: Argument list too longCommon causes
- A directory holds a very large number of files (cache, sessions, mail queue, uploads) and the pattern matches them all.
- The limit
ARG_MAXfor arguments plus environment of one program call is exceeded. - Very long file names make the total size reach the limit with fewer files.
- A huge environment (many or large variables) leaves less room for the arguments.
Check
- What is the limit on this system?
getconf ARG_MAX - How many entries are in the directory? (ls -f does not sort, so it is fast)
ls -f /var/spool/app/cache | wc -l - What would the pattern match? Print first, do not delete yet
find /var/spool/app/cache -maxdepth 1 -type f -name '*.tmp' -print | head -n 20 - Stack limit that the argument limit is based on
ulimit -s
Fix
- Let
finddo the matching instead of the shell. First look at the result with-print, then delete:find /var/spool/app/cache -maxdepth 1 -type f -name '*.tmp' -delete. This removes the files for good. - Run a command in batches:
find DIR -maxdepth 1 -type f -name '*.log' -exec gzip {} +. - With xargs and safe names:
find DIR -maxdepth 1 -type f -name '*.jpg' -print0 | xargs -0 -n 500 mv -t /target. - Narrow the pattern to a part of the files, for example
rm 2024-01-*, only as a workaround. - Find out why so many files pile up (cleanup job, session handling, logrotate) and fix that.
FAQ
Does raising ulimit -s help?
It can raise the limit, but it is a workaround. find -exec or xargs work with any number of files.
Why is rm -rf on the directory not affected?
Without a * the shell passes one name only. rm -rf DIR deletes the whole directory, so use it only if you really want all of it gone.