How to cause "Argument list too long" error?
Using getconf ARG_MAX
to generate a long list of x
and calling an external utility with that as its argument would generate an "Argument list too long" error:
$ /bin/echo $( perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long
The environment and the length of the string /bin/echo
will be included in what makes the error occur, so we can try to find the biggest possible number by subtracting these:
$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin
(I started this shell with env -i sh
, so there's only the PATH
variable in the environment)
$ /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo"))' "$(getconf ARG_MAX)" )
sh: /bin/echo: Argument list too long
Still too long. By how much?
i=0
while ! /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo") - $ARGV[1])' "$(getconf ARG_MAX)" "$i" )
do
i=$(( i + 1 ))
done
This loop exits for i=8
.
So there's four bytes that I can't immediately account for (four of the eight must be for the name of the PATH
environment variable). These are the null terminators for the four strings PATH
, the value of PATH
, /bin/echo
and the long string of x
characters.
Note that each argument is null terminated, so the more arguments you have to the command, the shorter the combined length of them can be.
Also, just to show the effect of a big environment:
$ export BIG=$( perl -e 'print "x" x $ARGV[0]' "$( getconf ARG_MAX )" )
$ /bin/echo hello
sh: /bin/echo: Argument list too long
$ /bin/echo
sh: /bin/echo: Argument list too long
On many Linux distributions, you can find out what's the current value of ARG_MAX by running
getconf ARG_MAX
A simple way to generate the message "Argument list too long" is to actually supply a long argument list; for example, on my system
/bin/echo "$(find / -xdev 2> /dev/null)"
works, but
/bin/echo "$(find / -xdev 2> /dev/null)" "$(find / -xdev 2> /dev/null)"
produces
bash: /bin/echo: Argument list too long
For an in-depth discussion, see "Argument list too long error for rm, cp, mv commands" on Stack Overflow.
P.S. The length in question is the actual amount of memory needed to store the arguments and environment. It is not related to the number of arguments.
Instead of listing all the files on the system, which takes forever and doesn't work on sparse systems, the command
/bin/echo {1..200000}
is a much faster (163ms) way to generate the error. For me ARG_MAX
is 2097152
(2,097,152 on the order of 2 million) but the command still errors.
If your shell doesn't have {start..end}
, you can use the somewhat slower (but still faster than listing files)
/bin/echo $(seq 1 200000)
If either command doesn't work, just increase the end value until it does, until bash
runs out of memory, or until seq
can't count any higher.