/errors/coreutils/argument-list-too-long
bash: /usr/bin/rm: Argument list too long
- tool
- GNU coreutils
- exit code
- 126
- versions
- Linux, macOS
- os
- linux, macos
Argument list too long is the text of the E2BIG error: the kernel refused to start the program because its arguments plus environment exceed the size limit for execve (ARG_MAX, often 2 MiB on Linux). It typically appears with rm *.log, cp * dest/ or mv in a directory with a very large number of files, because the shell expands the glob into one argument per file before running the command. Replace the glob with find, which handles any number of files: find . -maxdepth 1 -name '*.log' -delete.
The message comes from the shell that tried to run the program, so it names the program's path: bash: /usr/bin/rm: Argument list too long (exit status 126). zsh prints zsh: argument list too long: rm.
Check the limit
getconf ARG_MAX # bytes available for arguments + environment
xargs --show-limits </dev/null # GNU xargs: the limits it will useOn Linux the limit is a quarter of the stack size limit (ulimit -s), with a minimum of 128 KiB, and each single argument is also limited to 128 KiB.
Fixes
# delete matching files without building an argument list
find . -maxdepth 1 -type f -name '*.log' -delete
# run a command on batches of files
find . -maxdepth 1 -type f -name '*.log' -exec gzip {} +
find . -maxdepth 1 -type f -name '*.log' -print0 | xargs -0 mv -t archive/
# shell loop: one exec per file, slower but simple
for f in *.log; do mv -- "$f" archive/; done-maxdepth 1 keeps find in the current directory, like the original glob; remove it to include subdirectories. -exec ... {} + and xargs pass as many names per command as fit within the limit, so there are few process starts.
Builtins are not affected
echo * and printf '%s\n' * work with any number of files, because builtins run inside the shell and do not call execve. printf '%s\0' *.log | xargs -0 rm is therefore another fix.