Thank you (for making the ports less boring).

Oliver Fromme olli at lurza.secnetix.de
Wed Sep 14 11:11:51 UTC 2011


Stephen Montgomery-Smith wrote:
 > On 09/13/2011 09:11 AM, Oliver Fromme wrote:
 > > Stephen Montgomery-Smith wrote:
 > > >  particularly nasty thing to do.  I get the impression that each
 > > >  committer has his own special way of doing this.  For example, I have
 > > >  personally found that a simple grep won't work, because "grep xxx
 > > >  /usr/ports/*/Makefile*" just creates a line too long for the shell to
 > > >  handle.  I use a shell construction involving "find" but I wonder how
 > > >  others do the same thing.
 > > 
 > > cd /usr/ports
 > > echo */*/Makefile* | xargs grep xxx
 > 
 > That's amazing.
 > 
 > It would never have occurred to me that "echo */*/Makefile*" works when 
 > "grep xxx */*/Makefile*".  Is that because "echo" is a builtin command 
 > in csh (which is what I use)?  I notice "/bin/echo */*/Makefile*" 
 > doesn't work.

Yes, exactly.  When the shell executes an external command,
it uses the execve(2) syscall, which has a limit for the
size of the argument list.  This is why xargs(1) exists.
In the past century this limit was 64 KB, then it was raised
to 256 KB when people started measuring RAM in GB.  There's
a read-only sysctl for that value:

$ sysctl kern.argmax
kern.argmax: 262144

Built-in commands are not affected by the limit because
they run inside the shell process itself, so the execve(2)
syscall is not involved.  echo(1) is a built-in command in
all common shells, so "echo ... | xargs" always works.
However, if you type /bin/echo, you force the shell to
execute the external command, so the limit applies again.

You can also write "for i in */*/Makefile*; do ..." or
similar (in /bin/sh) without worrying for limits, for the
same reason.

 > Is this documented somewhere?

Good question.  It should be mentioned in the shells' man-
pages, e.g. csh(1) mentions it in the "LIMITATIONS" section
(among other strange limitations specific to csh).  Also,
the xargs(1) manpage mentions ARG_MAX, and the execve(2)
manpage explains that the syscall will fail (errno E2BIG)
if "the number of bytes in the new process' argument list
is larger than the system-imposed limit".

I'm pretty sure that _every_ book on shell scripting will
explain the argument list limit, and how to circumvent it.

Best regards
   Oliver

-- 
Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing b. M.
Handelsregister: Registergericht Muenchen, HRA 74606,  Geschäftsfuehrung:
secnetix Verwaltungsgesellsch. mbH, Handelsregister: Registergericht Mün-
chen, HRB 125758,  Geschäftsführer: Maik Bachmann, Olaf Erb, Ralf Gebhart

FreeBSD-Dienstleistungen, -Produkte und mehr:  http://www.secnetix.de/bsd

"If Java had true garbage collection, most programs
would delete themselves upon execution."
        -- Robert Sewell


More information about the freebsd-ports mailing list