Re: Questions related to - Arg list too long - error

On Jun 30, 8:14 am, mb <mbsans1@xxxxxxxxx> wrote:
While ls, mv, cp,... fail with 'Arg list too long' error, the other
commands printf, echo, find,..., or a for loop don't fail, and I'm
trying to make sense how these different commands handle wild card
I'm expecting printf or echo to fail, given that initially, there is
wild card expansion done for them too, same as ls and friends, but no
issue for them.

ls(1), mv(1), cp(1) and find(1) are external commands, the shell needs
to execve(2) them. The shell may be able to handle the full wildcard
expansion of the arguments, but the external command may not be able
handle that many arguments (and/or their maximum length or combined
length, etc. - could also be a system call issue - see also my
further below).

Some testing done with ~ 150,000 files on Solaris 10, bash 3.00.16.

For bash(1), printf and echo would typically be those built-in to the

In general, shell will be rather to quite capable of doing wildcard
expansion that makes for very large number of arguments and/or quite
large arguments. If it could not, then it would then become much more
difficult to deal with such situations (though find(1) and/or C, etc.,
might come in quite handy in such a circumstance). As long as the
shell itself can reasonably handle the expansion, it's generally
relatively easy for the shell to also hand that data off in more
reasonably sized chunks.

It seems that ARG_MAX limit is an issue for ls, mv,... but not for
printf or echo.

See my comments about built-in vs. external and execve(2). There may
also be specific limits at the system call interface (execve(2) in

With find there is no apparent expansion done, so no problem :

find(1) doesn't do wildcard expansion, it does pattern matching - i.e.
for any given file, does it or does it not match the pattern.

And with a for loop, again no apparent expansion done:
$ for i in *

The shell does the wildcard expansion, for is a shell built-in.

So I'd like to know why ARG_MAX limit applies to ls, mv, causing them
to fail, and not for printf or echo ?

See my comments further above.

Also when or how is wild card expansion done for find command and a
for loop ?

find(1) doesn't - see my comments further above.

for loop - may depend precisely how one is doing it, but in the more
simple cases, it's simply being done by the shell, e.g.:
for foo in *; do echo "\$foo=$foo"; done; unset tmp