Skip to content

/errors/coreutils/argument-list-too-long

bash: /usr/bin/rm: Argument list too long

The commands on this page have not been executed by our verification runner yet.updated
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

bash
getconf ARG_MAX          # bytes available for arguments + environment
xargs --show-limits </dev/null   # GNU xargs: the limits it will use

On 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

bash
# 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.

Sources