> > However this is not what happens in Exim 4.76 (Ubuntu 12.04) and Exim
> > 4.82 (Ubuntu 14.04). Instead matchposters.py is invoked with only *one*
> > command line argument as the empty $return_path is scrubbed out of the
> > argument list entirely. As far as I can tell there is no way to stop
> > this from happening.
>
> Quote it.
>
> > I don't believe that this is desirable. I feel strongly that command
> > line expansions should not vary a command's argument count based on
> > whether or not some expansions happen to be empty. At a minimum doing
>
> I tested if I could see what you were seeing. I ran:
> sudo exim -d+all -be '${run {/bin/cat $local_part /etc/passwd}}'
>
> It did exactly as I expected:
>
> 12:42:35 25840 expanding: /bin/cat $local_part /etc/passwd
> 12:42:35 25840 result: /bin/cat /etc/passwd
> 12:42:35 25840 direct command:
> 12:42:35 25840 argv[0] = /bin/cat
> 12:42:35 25840 argv[1] = /etc/passwd
> 12:42:35 25840 expanding: ${run {/bin/cat $local_part /etc/passwd}}
>
> I think you do the same thing as when you're running it from the shell
> to get this positional adherence: quote it:
> sudo exim -d+all -be '${run {/bin/cat "$local_part" /etc/passwd}}'
>
> 12:44:56 25952 expanding: /bin/cat "$local_part" /etc/passwd
> 12:44:56 25952 result: /bin/cat "" /etc/passwd
> 12:44:56 25952 direct command:
> 12:44:56 25952 argv[0] = /bin/cat
> 12:44:56 25952 argv[1] =
> 12:44:56 25952 argv[2] = /etc/passwd
> 12:44:56 25952 expanding: ${run {/bin/cat "$local_part" /etc/passwd}}
>
> > At a minimum I feel that this should be explicitly documented in
> > the ${run} section of the String Expansions chapter of the Exim
> > documentation.
>
> I thought it was standard commandline processing. Note that exim does
> not start a shell unless you include it in your command. It just
> exec's the program with args directly (which is why you don't get any
> kind of environment unless you specifically source env files). Are
> you saying that normally you do not have to quote args that are empty?
> In what? Or are you implying something else that I'm not quite
> understanding?
Until now I didn't know that quoting things in ${run ...} did anything;
that isn't documented either from what I can see. My assumption had been
that Exim first split the unexpanded ${run} command and arguments on
whitespace, creating:
argv[0] = /bin/cat
argv[1] = $local_part
argv[2] = /etc/passwd
and then expanded each in place. If an argument wound up empty after
expansion, it would be preserved (as empty). This was based on the
documentation wording that 'the command and its arguments are first
expanded *separately*' (emphasis mine).
What is and should be ${run}'s quoting and quote-stripping
behavior? There are real questions here if the answers are not
officially documented. For example, if $local_part includes a " and you
wrote:
${run {/bin/echo "$local_part"}}
what happens? Suppose you have a $local_part value that is:
alocal"part
Are only the outside 'literal' quotes stripped, resulting in:
argv[1] = alocal"part
or do you wind up with something like:
argv[1] = alocalpart"
(where it started out as '"alocal"part"' and had the first two quotes
interpreted as a quoted string that was dequoted)
Or you could even get an error.
It's my strong opinion that all of this should at least be
documented. I can work out what the answers are on any specific Exim
version but anything I do there is relying on undocumented behavior and
we all know what happens sooner or later with undocumented behavior.
- cks