Re: GNU Bash v.4.4.23-5 built-in function 'set' produces variable outputs
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
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
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
Environment variable "PS4" can not be passed to bash script from version 4.2.46(2)
Hello, I found a strange phenomenon, just as the subject, environment variable "PS4" cannot be passed to bash script, but any other variable, even self-defined variable can be passed to bash script. My bash version is "GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)", I downloaded an old version bash-2.0.tar.gz from ftp://ftp.gnu.org/gnu/bash/ and installed, no such issue found, "PS4" works well. I tried to set PS4 in /etc/profile, in /etc/bashrc, and export PS4 in terminal, just like below, it is correct in current terminal, but cannot be passed to bash script. export PS4='+[#$LINENO ${FUNCNAME[0]}() $BASH_SOURCE] ' export FAN='Myself' Then source /etc/profile, /etc/bashrc, I also tried to reboot my machine. In terminal, it works well: [root@fchen ~]# echo $PS4 +[#$LINENO ${FUNCNAME[0]}() $BASH_SOURCE] [root@fchen ~]# echo $FAN Myself But in Bash script, it cannot work, it keeps its original value: [root@fchen ~]# cat test.sh #!/usr/bin/bash echo $PS4 echo $FAN [root@fchen ~]# bash test.sh bash test.sh + Myself Value of variable "Fan" I set in /etc/profile is correct, but $PS4 keeps its original value. I tried many different variable names, such as "PS3", "PS5", all of them work, except "PS4". I found such problem when we update our os from Red-hat 7.3 to Red-hat 7.4,this is a long time ago. Now, I know that on Red-Hat7.0, bash version 4.2.45(1)-release, no such problem; on Red-hat 7.5 bash version 4.2.46(2)-release, on Ubuntu 16.04 bash version 4.3.48(1)-release, both have this issue. I assume this issue occurs after version 4.2.46. PS4 is used by "set -x" to prefix tracing output, it is very useful for our work, but it doesn't work now, I'm confused. Thanks a lot. Thanks, Fan
Re: Environment variable "PS4" can not be passed to bash script from version 4.2.46(2)
On Tue, Oct 23, 2018 at 03:20:12PM +, Chen, Farrah wrote: > But in Bash script, it cannot work, it keeps its original value: > [root@fchen ~]# cat test.sh > #!/usr/bin/bash > echo $PS4 > echo $FAN This is because you're doing it as root. Bash strips PS4 from the environment when started as root, as a security precaution. wooledg:~$ PS4='hello' bash -c 'set -x; true' hellotrue wooledg:~$ sudo env PS4='hello' bash -c 'set -x; true' [sudo] password for wooledg: + true Notice how it works as expected as a regular user, then "fails" under sudo.
Re: Environment variable "PS4" can not be passed to bash script from version 4.2.46(2)
On 10/23/18 12:06 PM, Greg Wooledge wrote: > On Tue, Oct 23, 2018 at 03:20:12PM +, Chen, Farrah wrote: >> But in Bash script, it cannot work, it keeps its original value: >> [root@fchen ~]# cat test.sh >> #!/usr/bin/bash >> echo $PS4 >> echo $FAN > > This is because you're doing it as root. Bash strips PS4 from the > environment when started as root, as a security precaution. That change came in in bash-4.3 (patch 48). His vendor probably patched their version of bash-4.2 to do the same thing. -- ``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
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: Environment variable "PS4" can not be passed to bash script from version 4.2.46(2)
Got it, thanks for the info. Thanks, Fan -Original Message- From: Chet Ramey [mailto:chet.ra...@case.edu] Sent: Wednesday, October 24, 2018 4:48 AM To: Chen, Farrah ; bug-bash@gnu.org Cc: chet.ra...@case.edu Subject: Re: Environment variable "PS4" can not be passed to bash script from version 4.2.46(2) On 10/23/18 12:06 PM, Greg Wooledge wrote: > On Tue, Oct 23, 2018 at 03:20:12PM +, Chen, Farrah wrote: >> But in Bash script, it cannot work, it keeps its original value: >> [root@fchen ~]# cat test.sh >> #!/usr/bin/bash >> echo $PS4 >> echo $FAN > > This is because you're doing it as root. Bash strips PS4 from the > environment when started as root, as a security precaution. That change came in in bash-4.3 (patch 48). His vendor probably patched their version of bash-4.2 to do the same thing. -- ``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
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 sho