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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to