Subject: bug#20733: coreutils build problem

From: Eric Blake <[email-masked]>
Date: Thu, 04 Jun 2015 14:41:08 -0600

On 06/04/2015 02:17 PM, Nick Bowler wrote:
> Do these problematic shells properly handle:
> 
>   for arg
>   do
>     ...
>   done
> 
> when $# is 0?

Yes; all shells do.

$ /bin/sh -c 'echo $#; for arg
do echo hi; done; echo bye'
0
bye

> 
> If so, can we use the following as a workaround?
> 
>   set x words-that-might-expand-to-nothing; shift
>   for arg
>   do
>     ...
>   done

Not ideal, when there are shorter invocations that can do the same.  And
it's not the expand-to-nothing that is a problem, it is the actual omission:

$ /bin/sh -c 'for a in ; do :; done'
/bin/sh: syntax error at line 1: `;' unexpected
$ /bin/sh -c 'for a in $nothing; do :; done'
$

so anything that expands in shell to nothing (whether $nothing, ``, or
use of a shell variable rather than a make variable) is fine; the
problem is most common in Makefiles where make variables are expanded
before the shell sees anything.

> 
> I suppose that might be hard to do in this /particular/ case, as it
> looks like the error is coming from a make rule.  The Autoconf manual
> quite emphatically says to avoid 'for arg; do ...' by using a newline
> instead of a semicolon, a feat which is not easily done in make rules.

The manual also has a workaround for getting a literal newline in make
rules:
 nlinit=`echo 'nl="'; echo '"'`; eval "$$nlinit"

although that only gives you $nl containing newline, and you'd still
need another layer of 'eval' if you wanted to actually write the
makefile fragment to interpret the newline as a separator between the
var-name and 'do'.  So yeah, it's not worth it.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org