Eric Blake wrote: > On 11/06/2010 08:19 AM, Jim Meyering wrote: >> Andreas Schwab wrote: >> >>> Jim Meyering <j...@meyering.net> writes: >>> >>>> Here's a better test case: >>>> >>>> $ /bin/sh -c 'f(){ local s=$IFS; test -n "$s"; }; f' >>>> [Exit 1] >>>> >>>> And based on that, here's a patch to gnulib's tests/init.sh >>>> that solves the problem more generally: >>>> (but this is not enough for coreutils, since some >>>> failing tests don't yet use init.sh) >>> >>> Why not just add the quotes? This isn't formally an assignment, so the >>> behaviour of the shell is reasonable after all. >> >> Actually, I'm doing both for the upcoming release. >> Adding the quotes as a stop-gap measure, because it feels like a >> kludge. I'll remove it once I've converted all tests to use init.sh. >> IMHO, the fact that VAR=$OTHER_VAL never needs quotes >> should imply that `local VAR=$OTHER_VAL' also requires no quotes. > > Local is not required by POSIX.
Yes, that is unfortunate. However, without it, we end up perpetrating unspeakable crimes upon variable names -- or violating user name-spaces, or simply writing uglier code than we could have with "local". As to whether all users of init.sh can deal with this additional constraint, I have my doubts, and hence I have not pushed the change to the gnulib repository. It may make sense to allow that shell-selection snippet to be customized via some new separate file, say init.early, that would be sourced early on. > If local is a normal application, then > it requires quotes. Only shells that provide it as a special builtin, > like bash, can support 'local s=$IFS' without needing the quotes. > > By the way, if you insist on having 'local', even though it is not > POSIX, you could at least work around the BSD shell issue by: > > local s > s=$IFS Thanks, but while that would be good enough for now, there's no telling whether a similar use appearing a few months from now would be caught in review. Requiring a sensible shell -- thus relieving us of the burden of remembering yet another portability quirk -- is one of my favorite flavors of defensive programming. > rather than joining the assignment in the same expression as the > declaration. This is a good habit to get into anyways, since: > > local s=$(false); echo $? > 0 > local t; t=$(false); echo $? > 1 > > that is, local is an expression of its own, and succeeds if the > assignment completed, throwing out the status of any command > substitutions used to compute that value; while doing assignment on its > own line has nothing to override the command substitution value. Thanks! I didn't know about that one, and in fact had a few (mis)uses matching just that pattern in my shell startup files: local rev=$(< $pv) || return 1 Rewrote it as you'd expect, now: local rev rev=$(< $pv) || return 1