On 11/05/2010 12:17 PM, Jonathan Nieder wrote: > Hi, > > Current shells differ in how they split words in the arguments to > 'export' and similar builtins: > > A. Costa wrote: > >> % foo() { export x="$@" ; } >> % foo -f --c >> export: 4: --c: bad variable name >> % echo $? >> 2 >> >> It seems like it should be standard code. >> >> Remove 'export' from 'foo()' and there's no error: >> >> % foo() { x="$@" ; } ; foo -f --c ; echo $? >> 0 >> >> I just tested the code in 'bash', 'ksh' and 'pdksh'; it works with no >> errors. Yet in 'posh' it gives a different error: > > "$@" can be a pain, so for avoidance of confusion let's take another > example. > > $ foo() { export x=$1; }; foo "-f --c" > export: 1: --c: bad variable name > > The split in behaviors between shells for this construct is the same. > > 1. Variable expansions in what is grammatically a variable assignment > or redirection do not undergo word splitting. Variable expansions > in command names and parameters do.[1] > > 2. According to the grammar, variable assignments must come before the > command name.[2] > > 3. "export" is a special builtin, not a keyword, so grammatically it > behaves just like any other command.[3] > > So posh and dash would seem to be correct, and the foo=bar arguments > to 'export' should be split. > > On the other hand, the suppression of word splitting in export, local, > and readonly arguments by bash, ksh, and pdksh is a nice behavior that > is not likely to break current scripts. Would it make sense to tweak > the word splitting rules[1] to allow this behavior?
I would love to require altered word splitting behavior for export and readonly (the standard doesn't touch local yet). In fact, it has independently come up on the GNU coreutils development lists that the standard is long overdue for requiring shells to support 'local' in shell functions, and that standardizing local would be another reason why word splitting rules would need to be modified. Consider: $ mkdir /tmp/t && printf '#!/bin/sh\necho you lose\n' > /tmp/t/cat && chmod a+x /tmp/t/cat $ dash -c 'f() { b="1 PATH=/tmp/t"; local z=$b; cat whatever; }; f' you lose $ bash -c 'f() { b="1 PATH=/tmp/t"; local z=$b; cat whatever; }; f' cat: whatever: No such file or directory Would you like me to take a stab at writing the bug report(s) to add support for 'local' in the next revision of the standard, and to require the ksh/bash behavior of suppressing word splitting after shell builtins that take arguments which can modify the current set of shell/environment variables? -- Eric Blake ebl...@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature