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