Re: wrong behaviour when unsetting/setting some variables
Harald van Dijk <[email protected]>
| Newsgroups | org.kernel.vger.dash |
|---|---|
| Message-ID | <[email protected]> |
On 29/02/2024 18:45, Martijn Dekker wrote:
> Op 29-02-2024 om 18:07 schreef Harald van Dijk:
>> On 29/02/2024 17:41, Martijn Dekker wrote:
>>> Op 28-02-2024 om 00:56 schreef Harald van Dijk:
>>>> However, trying to fix this I come across a corner case where it is
>>>> not clear to me what the intended behaviour is.
>>>>
>>>> set -a; readonly foo=bar; export # some shells export, not all
>>>
>>> IMO, the shell should export it in that case; POSIXly, 'set -a'
>>> should cause the variable to be exported whenever a value is
>>> effectively assigned to it (whether this is by a "true" shell
>>> assignment, an assignment-argument, an expansion like ${foo=bar} or
>>> ${foo:=bar}, indirectly by 'read' or 'getopts', or maybe other cases
>>> I'm not thinking of).
>>
>> Spec-wise, the thing that troubles me is that the option is specified as
>>
>> > When this option is on, the export attribute shall be set for each
>> > variable to which an assignment is performed; see XBD Variable
>> > Assignment.
>>
>> where XBD Variable Assignment is only about the assignment syntax of
>> the shell, not other syntax or other commands even if they also cause
>> variables to become assigned.
>
> Yeah, that's confusing (and IMO should be fixed in the spec), but that
> same paragraph goes on to mention 'getopts' and 'read' as examples of
> utilities that perform assignments. In other words, though 'read var' is
> no XBD "Variable Assignment" assignment, it's stated explicitly that
> 'var', on which 'read' performs an assignment, should gain the export
> attribute.
Good point, though by special-casing getopts and read, it kind of
implies that it does not apply to other commands and utilities.
Anyway, now that I think we are on the same page about what shells
*should* do: in dash, a quick search suggests this should be the following:
* Substitutions may perform assignment (the ones you mentioned, plus
$((...)) arithmetic)
* The for command performs assignments to the loop variable.
* The cd command sets PWD and OLDPWD.
* The getopts command does not merely assign to the specified variable,
also to OPTARG and OPTIND.
* The local and readonly commands perform assignments to specified
variables.
* Every command causes a value to be assigned to LINENO.
* Every simple command causes a value to be assigned to _.
The way I implemented LINENO, the implicit export does not work for
that, and for consistency, it should, even if no one is going to be
relying on that. I have not gone over the other ones to check if they
are all handled correctly.
Cheers,
Harald van Dijk