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

2018-10-24 Thread Chet Ramey
On 10/24/18 2:51 AM, Robert Elz wrote:


> 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.)

Of course not -- it succeeds. Bash simply sets the variable again. This
is one of the special things about _.


> 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.

Sloppy documenting, though ksh93 uses the same language: it really means
`simple command', and foreground simple commands at that.


-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



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

2018-10-24 Thread Robert Elz
Date:Tue, 23 Oct 2018 15:37:15 -0600
From:Bob Proulx 
Message-ID:  <20181023151944393472...@bob.proulx.com>

  | 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  is historical practice, its overloaded 
usage
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
  | > _=SSLKEYLOGFILE
  | > $ 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 

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

2018-10-23 Thread Bob Proulx
Robert Elz wrote:
> ps: I did  not suggest that $_ should go away, I know that's not going to
> happen ... just that it would be nice for those who really don't want it to
> be able to turn it off.

I'm having a hard time understanding why one would want to turn off
this feature.  It isn't something that everyone uses but it is a
feature that has a lot of use.  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.  That just seems
extreme.  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.  The original report wasn't really about $_ anyway.

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

The original report was about the output being different in different
invocations.  But I think that is an invalid reason.  Because if so
then 'echo $RANDOM' is also a bug because it produces different output
in different invocations too.  And because set | grep is not a correct
way to look at the environment as such either.  The 'set' command is
designed to set or unset shell options or the positional parameters.
Without any arguments "set shall write the names and values of all
shell variables in the collation sequence of the current locale".
Since $_ is a shell variable it writes it out along with possibly
other data too.  I don't think anyone grep'ing for a string should
complain that the shell also prints out the contents of $_.

As an additional point 'set' writes out the internal data which
includes a lot of *stuff*.  It would be better in this case to use
'env' to write out only the exported variables.  And clearly in the
original report the string being looked for was part of the exported
data.  There is no problem then.

  $ export SSLKEYLOGFILE=/home/user/test
  $ env | grep SSL
  SSLKEYLOGFILE=/home/user/test
  $ env | grep SSL
  SSLKEYLOGFILE=/home/user/test

However even 'env' isn't the appropriate tool either.  There may be
other variables that happen to hit the grep pattern.  And there is the
problem of the variable value including newlines.  The -z,--null helps
here but life isn't simple.

Not that I would do it this way but 'printenv' seems to be the right
matching utility here.

  $ export SSLKEYLOGFILE=/home/user/test
  $ printenv SSLKEYLOGFILE
  /home/user/test

Using grep is fine.  But then the human must interpret the results
accordingly.  I think here understanding that 'set' is doing what is
expected and reasonable is enough.  However I would use 'env' to avoid
the internal data state.  And programatically neither are sufficient
for a fully robust program and other methods should be used.

Bob



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

2018-10-23 Thread Greg Wooledge
On Tue, Oct 23, 2018 at 02:06:37PM +0700, Robert Elz wrote:
> Interactively you're much more
> likely to want !$ than $_ (I'd suggest infinitely more lijkely...)

You mean negative infinity.

wooledg:~$ grep histexpand .bashrc
set +o histexpand



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

2018-10-23 Thread Robert Elz
ps: I did  not suggest that $_ should go away, I know that's not going to
happen ... just that it would be nice for those who really don't want it to
be able to turn it off.

kre




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

2018-10-23 Thread Robert Elz
Date:Mon, 22 Oct 2018 09:37:19 -0400
From:Greg Wooledge 
Message-ID:  <20181022133719.g4wc7uuowwfff...@eeg.ccf.org>

  | I occasionally run a command like  mkdir /tmp/x && cd "$_"

cdnd()
{
mkdir -p "$1" && cd "$1"
}

Make it as fancy as you want.   Interactively you're much more
likely to want !$ than $_ (I'd suggest infinitely more lijkely...)

kre





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

2018-10-22 Thread Greg Wooledge
On Mon, Oct 22, 2018 at 12:54:42PM +0700, Robert Elz wrote:
> Scripts that want to use $_ (if there are any, which I doubt) won't be
> unsetting it and would continue to work, the rest of us (at least those of
> us not insane enough to try and use it) could just "unset _" in .profile (etc)
> and be done with it.

I occasionally run a command like  mkdir /tmp/x && cd "$_"



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

2018-10-21 Thread Robert Elz
Date:Fri, 19 Oct 2018 16:21:27 -0400
From:Grisha Levit 
Message-ID:  


  | I guess it's a bit surprising that $_ is set to just the variable name
  | and not "the last argument to the previous command", which would be
  | the full assignment string.

Except that a var assign isn't a command at all, but something different, and
one could argue that with no command $_ should retain its value from whatever
was the last command.   But $_ has so many different uses in bash (and ksh93) 
and was a horrible botch in the first place (from when it was first added to 
ksh) so what it does isn't worth being concerned about - as best as can be
done, simply ignore it, and hope it eventually goes away

kre

ps: it would be really nice if, in bash (and everywhere else) $_ could turn
into one of the magic vars which loses its special properties when unset.
Scripts that want to use $_ (if there are any, which I doubt) won't be
unsetting it and would continue to work, the rest of us (at least those of
us not insane enough to try and use it) could just "unset _" in .profile (etc)
and be done with it.




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

2018-10-19 Thread Grisha Levit
On Fri, Oct 19, 2018 at 3:51 PM Greg Wooledge  wrote:
> On Fri, Oct 19, 2018 at 09:41:41PM +0200, Ricky Tigg wrote:
> > $ set | grep SSL
> > SSLKEYLOGFILE=/home/user/test
> > _=SSLKEYLOGFILE

I guess it's a bit surprising that $_ is set to just the variable name
and not "the last argument to the previous command", which would be
the full assignment string.



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

2018-10-19 Thread Greg Wooledge
On Fri, Oct 19, 2018 at 09:41:41PM +0200, Ricky Tigg wrote:
> Built-in function 'set' produces variable outputs.

> $ export SSLKEYLOGFILE=/home/user/test
> 
> $ set | grep SSL
> SSLKEYLOGFILE=/home/user/test
> _=SSLKEYLOGFILE

This is not a bug.  The Special Parameter "_" is explained in the manual:

   _  At  shell  startup,  set to the absolute pathname used to invoke
  the shell or shell script being executed as passed in the  envi‐
  ronment  or  argument  list.   Subsequently, expands to the last
  argument to the previous command, after expansion.  Also set  to
  the  full  pathname  used  to  invoke  each command executed and
  placed in the environment exported to that command.  When check‐
  ing  mail,  this  parameter holds the name of the mail file cur‐
  rently being checked.

What you're seeing is simply that the varying content of $_ sometimes
matches your grep, and sometimes not.

wooledg:~$ true
wooledg:~$ echo "$_"
true
wooledg:~$ true blue
wooledg:~$ echo "$_"
blue
wooledg:~$ true blue | grep foo
wooledg:~$ echo "$_"

wooledg:~$ X=Y
wooledg:~$ echo "$_"

wooledg:~$ export X=Y
wooledg:~$ echo "$_"
X

In your example, after the export command, $_ contains "SSLKEYLOGFILE"
and therefore it matches your first grep.  However, after that grep
command finishes, $_ is empty (I don't know why -- possibly because each
"command" of the pipeline runs in a subshell?), and so it does NOT match
your second grep.