On 2007-12-05 at 15:28 -0800, Marc Perkel wrote:
> Getting error "Too many arguments in command ...... in ${run} expansion"
>
> Just wondering what the limitations are and how to fix it. Would
> eliminating spaces reduce the number of arguments or is it the length of
> the strings?
60 parameters.
${run} uses the same sub-command logic as the pipe transport, etc. Look
at transports.c:transport_set_up_command() for the details, where the
error message is, to see that the limit is:
max_args = address_count + 60;
address_count is calculated from the list of addresses that the function
was called with.
This is called from expand.c, look for the second instance of EITEM_RUN
and read down. The address array is passed as NULL and so address_count
will be 0.
Therefore you can pass 60 parameters for $run.
/* Get store in which to build an argument list. Count the number of addresses
supplied, and allow for that many arguments, plus an additional 60, which
should be enough for anybody. Multiple addresses happen only when the local
delivery batch option is set. */
Clearly Marc, you are not just anybody.
You can change the number and recompile, but if you're hitting 60
parameters then you're already past "a few" and you're "likely" to be
scaling with data, rather than a fixed set of parameters. It seems
unlikely that you'd not be risking a certain set of input data exceeding
the kernel's argv limit. To find this for your system:
$ getconf ARG_MAX
and this needs to have the environment too.
Checking to see if Linux had any special cases, I found:
<URL:
http://www.in-ulm.de/~mascheck/various/argmax/>
http://www.in-ulm.de/~mascheck/various/argmax/
which is informative.
So scaling argv with input data is a bad plan and you should consider
putting data in via another method (file, whatever). On the other hand,
if you're just having to pass a lot of parameters in to tune some
command, there are two work-arounds:
(1) Accept that you'll sometimes need to test this interface without
going through Exim and put the invocation incantation into a shell
wrapper which only requires you to set a couple of parameters.
(2) Change the magic number in transports.c and recompile Exim.
-Phil