Notes |
(0003931)
kre (reporter)
2018-03-08 21:42
edited on: 2018-03-08 21:45
|
I had not seen this issue earlier... I do not much like the resolution
approved, as it suggests that "unset" can undo the readonly attribute, which
has never been one of its functions.
The text does say that
Read-only variables cannot be unset.
but it does not say (explicitly) that the readonly attribute cannot be
removed - and if the text is now to say
and unset any attributes that have been given to name
(see section 2.14 export and readonly).
It reads to me as if it is saying that unset should be able to unset the
readonly attribute, and there is nothing that counters that.
The text as it currently exists (in TC2) says ...
If -v is specified, name refers to a variable name and the shell
shall unset it and remove it from the environment.
I have always interpreted "remove it from the environment" as including
"delete the export attribute" as if that were not to happen, the variable
would simply reappear in the environment when it is set again, and that is
not what any shell has ever done.
I agree that this section is not well written, and needs clarification
(particularly in that if -v is not specified, all it says is that the
variable should be unset - which could allow an implementation to leave
the value in the environment while deleting it from the current shell,
which is also not what should happen.)
So, I would suggest that the text should say something more like
If -f is set, each name refers to a function, and affects the named functions.
If -v is set, each name refers to a variable, and affects the named variables.
If both -f and -v are set, then both variables and functions are affected.
If neither -f nor -v is specified, name refers to a variable; if a variable
by that name does not exist, it is unspecified whether a function by that
name, if any, is affected.
Each variable to be operated upon by this command shall be unset,
removed from the environment, and have its export attribute (see the
export command in section 2.14) removed. Read-only variables (see the
readonly command in section 2.14) cannot be unset, and are not altered
in any way.
Each function to be operated upon by this command shall have its definition
deleted (the function shall be unset) so that no function of that name
continues to exist in the current execution environment.
Unsetting a variable or function that was not previously set shall not be
considered an error and does not cause the shell to abort.
(and the rest that currently follows the previous sentence, which is
unchanged.)
There should probably be something added related to attempts to unset readonly variables causing an error (at least exit status 1, and a diagnostic to stderr).
|
|
(0003932)
geoffclare (manager)
2018-03-09 11:06
|
Reopening as we need to address kre's comment. |
|
(0003933)
joerg (reporter)
2018-03-09 11:23
|
Well the Bourne Shell uses this algorithm since more than 35 years:
The unset C function in the shell resets all attributes (including the readonly attribute) when it does the actual unset.
It however first checks whether a variable is readonly and fails in this case before doing something with the variable. |
|
(0003934)
kre (reporter)
2018-03-09 13:05
|
Joerg - you mean it resets the readonly attribute that it already knows
is not set? And the only other attribute that exists is "exported"
right? So in practice, "resets all attributes" means "resets the
exported attribute, if set". I prefer to be explicit about what happens.
Where it makes a difference is for shells that have added more attributes
(not the one I work on I might add here). If "unset" claims that "all"
attributes are reset, then that would mean that some attribute that most
of us have never heard of (the "null on weekends" attribute) must be reset
by the "unset" command - yet the shell that invented that attribute might
not act that way, and perhaps for good reason.
We should specify what happens for attributes defined by the standard.
There are, as best I recall anyway, just 2 - exported and readonly.
Unset never resets readonly, so let's just be accurate and say that it
unsets the export attribute (and the value of course), and leave it at
that.
Whether attributes that other shells have are also unset is for the
documentation of those shells to specify. If any such attribute is
ever added to posix, then we would need to ammend this section, to
indicate whether it is cleared, or not, by the unset command. |
|
(0003935)
joerg (reporter)
2018-03-09 13:20
|
What I wanted to say is that Don may have looked at the Bourne Shell sources when writing his proposal. |
|
(0003937)
geoffclare (manager)
2018-03-15 15:56
|
On P 2395, L76342 (1st paragraph of unset DESCRIPTION section) change:
Each variable or function specified by name shall be unset.
to:
The unset utility shall unset each variable or function definition specified by name that does not have the readonly attribute and remove any attributes other than readonly that have been given to name (see section 2.14 export and readonly). |
|
(0003988)
hvd (reporter)
2018-04-21 08:01
|
I believe the currently accepted text would mean that it is no longer an error to attempt to unset a readonly unexported variable: unset is specified to simply do nothing in that case, which cannot fail.
I believe the currently accepted text is unclear on whether it would be an error to attempt to unset a readonly exported variable: unset is specified to only remove the export attribute, but is silent on whether that attempt will succeed. (Note: this is similar to the question of whether the export attribute can be added to a readonly variable. Implementations vary, and in those that allow it, there is further variance in whether extensions such as typeset +x allow the attribute to subsequently be removed.)
Shells do treat both of these as an error and should continue to do so. I think the originally proposed wording was on the right track for handling that, but the failure to unset a variable should imply that its attributes will not be modified, in which case it does not matter whether unset is specified to unset the readonly attribute. |
|