[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GNU Bash v.4.4.23-5 built-in function 'set' produces variable output

From: Robert Elz
Subject: Re: GNU Bash v.4.4.23-5 built-in function 'set' produces variable outputs
Date: Wed, 24 Oct 2018 13:51:20 +0700

    Date:        Tue, 23 Oct 2018 15:37:15 -0600
    From:        Bob Proulx <address@hidden>
    Message-ID:  <address@hidden>

  | I'm having a hard time understanding why one would want to turn off
  | this feature.

Because I regard it as a design bug (from ksh, copied into bash) not
as a feature.   Note that while much of ksh was copied into POSIX, this
little bit was not  ... that of itself should be something of a hint....

     _ (Underscore.) While <underscore> is historical practice, its overloaded 
                        in the KornShell is confusing, and it has been omitted 
from the Shell and
                        Utilities volume of POSIX.1-2008.

But if you like it, then fine, no-one is wanting to take it away...

  | It isn't something that everyone uses but it is a
  | feature that has a lot of use.

If you mean it does a half dozen different things in different contexts,
then yes, that is a lot of use, too much...

  | If one goes down that path then the
  | end result taken to the logical extreme would be that every feature
  | would have a control to turn them on and off.

Not at all.   Most simply do nothing if not used.   If you don't use
arrays (as one example) then you simply don't know they're there.
The same is true of almost everything.   But $_ keeps on getting in
the way.

  | And for the case of $_ if you didn't know it existed then
  | one probably goes about their life continuing to not be bothered
  | by it too.

Depends upon what you call "bothered".   Unless one wants to use
_ as a variable name (which should really be possible, though is
not all that likely) it doesn't usually do a lot of direct harm, but it
does keep intruding in places where it is not wanted.

I have complained about this (in private) to Chet before ... there are
times when I want to run commands with a complely empty environment,
but no matter how I try to make it go away, that _ keeps sticking its
nose in...   The rest of what bash (by default) adds to the environ
(like SHLVL as one example)  can be removed by unset, but not _
(though "unset _" does not fail.)

  | The original report wasn't really about $_ anyway.

Actually it was, that was the exact issue:

  | Ricky Tigg wrote:
  | > Built-in function 'set' produces variable outputs.
  | > $ export SSLKEYLOGFILE=/home/user/test
  | > $ set | grep SSL
  | > SSLKEYLOGFILE=/home/user/test
  | > $ set | grep SSL
  | > SSLKEYLOGFILE=/home/user/test

Sometimes _=... is there, sometimes it is not.   That's the
"variable output".

Note that it isn't really even following its doc, here, among its
uses, this one would be from ...

        expands to the last
              argument to the previous command, after expansion.        

which for the second "set | grep" above, was the previous
"set | grep SSL" and the last arg there was "SSL" which should
have matched the grep pattern.

Don't bother explaining why that didn't happen, I know why, but
it does make _ even more useless than it would be otherwise
(which is not an easy thing to accomplish, so well done!)

  | The original report was about the output being different in different
  | invocations.  But I think that is an invalid reason.

Once you know what and why, it is possible to follow what is
happening, but it is confusing, and unnecessary.

  | Because if so then 'echo $RANDOM' is also a bug because it
  | produces different output in different invocations too.

Nonsense,   One is expecting $RANDOM to produce different
values, it is expected to be there, and it is documented that
way.   But note that in bash, for some reason,the "set" command
does not incllude RANDOM in its output (I don't know if this is
fixed in bash 5) (LINENO is also missing, whereas most other
magic vars, including stuff like OPTIND, DIRSTACK, and BASH_LINENO,
are there).

  | And because set | grep is not a correct
  | way to look at the environment as such either.

To look at the environment, no, but whoever said anything about that?
The original message just said that "set producess different outputs"
That the var was created in an export command so that it would be
exported into the environment is just a happenstance, the same would
have happened without the "export".

  | The 'set' command is
  | designed to set or unset shell options or the positional parameters.

Yes, but that part isn't relevant here, this is:

  | Without any arguments "set shall write the names and values of all
  | shell variables in the collation sequence of the current locale".

Exactly, so he was looking for what shell variables contained "SSL"
(in their names or values).   Had there been others, their source could
have been tracked down, and either verified, or removed.   But that _
which is sometimes there, sometimes not ... what's that?   [Don't answer.]

  | Since $_ is a shell variable it writes it out along with possibly
  | other data too.

Actually, it isn't (a shell variable) according to the man page,
so it shouldn't have been there at all ... but that I think is really
a man page error (see below).

  | I don't think anyone grep'ing for a string should
  | complain that the shell also prints out the contents of $_.

No, nor do I, but that it was there sometimes, not there
others, and with no seemingly logical explanation, and
there is no way to "fix" it.

What is the problem with _ being just like (extracts from the
bash man page...)

        If BASH_ALIASES is unset, it loses its special
        properties, even if it is subsequently reset.

        If DIRSTACK is unset, it loses its special properties,
        even if it is subsequently reset.

        If HISTCMD is unset, it loses its special properties,
              even if it is subsequently reset.

        If LINENO is unset, it loses its special
              properties, even if it is subsequently reset.

        If RANDOM is unset, it loses its special properties,
        even if it is subsequently reset.

(there are more just the same, and others, like HOSTNAME,
which are not documented to act this way, still do.)

Note also that in the bash man page, _ is not even listed in the

       Shell Variables
        The following variables are set by the shell:

(and of course, not in the subsequent list of vars used by the
shell, but not set by it (other than at init time).)  but is documented
as if it were a special parameter, which it isn't  - special params
don't go in the environment, ever (they are not variables), they don't
appear (ever) in the output of the "set" command, and
one cannot attempt to assign to them, whereas ...

        bash -c '_=foo; echo $?'

(the special params all have names which cannot be
variable names.)   That is, someone looking to see what
this _ "variable" might be, is quite likely to miss it.

The rest of your message has nothing to do with this point.

Which command, and how, should be used depends upon exactly
what was needed (the point of the original command) which we were
not told, so there are lots of possible better ways.  Whch should be
used we cannot say without more info.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]