Re: bug#20733: coreutils build problem
On 2015-06-04 14:41 -0600, Eric Blake wrote: 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. OK, good to know. [...] 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' $ Right, I see that now in the doc patch you posted. So in Autoconf this might turn up if you generate the list with m4, but is highly unlikely to be an issue for pure shell code. Thanks, -- Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Re: bug#20733: coreutils build problem
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 signature.asc Description: OpenPGP digital signature
Re: bug#20733: coreutils build problem
Eric Blake wrote: Actually, POSIX_does_ allow for missing words between 'in' and the terminator (; or newline) before 'do' (whether by a word that expands to nothing, or by omission of words), requiring that the body of the for statement is skipped in that case: Ah, sorry, I was thinking of previous versions of POSIX, which required at least one word after the 'in'. You're right, the current POSIX version doesn't require this any more. So the Solaris sh in question is conforming to the old POSIX standard but not to the current one. I liked the approach with ``; I hadn't thought of that. I used the coreutils fix I did because other coreutils code already fixed similar for-loop problems that way.
Re: bug#20733: coreutils build problem
On 2015-06-04 13:34 -0600, Eric Blake wrote: [adding autoconf] On 06/04/2015 01:17 PM, Paul Eggert wrote: On 06/04/2015 09:41 AM, Michael Felt wrote: GEN src/coreutils.h /bin/sh: 0403-057 Syntax error at line 1 : `;' is not expected. Port to POSIX shell, which doesn't allow 'for i in ; do ...'. Actually, POSIX _does_ allow for missing words between 'in' and the terminator (; or newline) before 'do' (whether by a word that expands to nothing, or by omission of words), requiring that the body of the for statement is skipped in that case: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04 But it is also true that older shells did not always follow this rule, so you are indeed better off always supplying at least one word that won't be expanded into nothingness. Hmmm, I thought that autoconf would document it as a portability pitfall, but I don't see it under 'for' in this link: https://www.gnu.org/software/autoconf/manual/autoconf.html#Limitations-of-Builtins Yikes! Some questions: Do these problematic shells properly handle: for arg do ... done when $# is 0? If so, can we use the following as a workaround? set x words-that-might-expand-to-nothing; shift for arg do ... done 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. Cheers, -- Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)