Re: Missing documentation "-bash_input"
Date:Tue, 28 Nov 2023 19:27:17 -0500 From:=?UTF-8?Q?Lawrence_Vel=C3=A1zquez?= Message-ID: | the first argument after the command string (in my case "a", and | in your case "-bash") is used as $0 while executing that command | string, and the remaining arguments are used as the positional | parameters. This happens even if an argument looks like an option, | so options are not recognized as such if they follow -c [*]: I had expected that the '[*]' footnote was going to correct things and explain that while what you said was more or less right, it isn't correct, which a variation on your example will show... | % bash -x -c 'printf %s\\n "$0"' | + printf '%s\n' bash | bash % bash -c -x 'printf %s\\n "$0"' + printf '%s\n' bash bash The -c option isn't followed by the command to execute, if it were then ... | % bash -c 'printf %s\\n "$0"' -x | -x wouldn't operate like it does, as -x would then be an option. Rather -c (nd -s) tell the shell how to interpret the args that follow once all the options have ended, as in for example % bash -c -x -- -q + -q bash: line 1: -q: command not found "--" or any arg not starting wih '-' end the options, in shells, just like in most other commands (with the -- otherwise being ignored, other options not). If -c was given, then at least one non-option arg is required, the first is the command string, the remainder, if any, are as you explained. If -s is given then the remaining args become $1, $2 ... and $9 is unchanged (commands are then read from stdin). Giving both -s and -c produces results that vary from shell to shell,, so don't do that! Otherwise, if there are args, the first is the name of a file, from which commands are read, and which also becomes $0, the remainder, if any, become $1 $2 ... for the script. Otherwise (no -s, no -c, no args) we simply have a nomaal shell which reads stdin for commands, uses its own name as $0 (which it also does with -s, or with -c when no replacement $0 is given) and is interactive if stdin and stderr are terminals (and in some shells, if -i was given, but don't rely upon that). And then: | From:Klaus Frank | Subject: Re: Missing documentation "-bash_input" | One thing though, I probably should already know that, but why is a $0 | needed even though a command was already specified? Shouldn't the | command itself be $0? What command? Consider bash -c 'while sleep 5; do printf %s\\n "$0"; done' What would you expect $0 to be set to in that case? Here, it would just be "bash" as no new $0 was given (try it, but note you need to wait 5 secs before the first output appears, then 5 more for each following copy of that...), or with bash -c 'while sleep 5; do printf %s\\n "$0"; done' foo it will be "foo". What else could it reasonably be? "while" ??? Also, try adding -x, before the -c, after the -c, combined with the -c (as -cx and -xc) and instead of "foo", and observe what happens then as well.Read the manual page first (all of it) and then experiment. If you're going to go to the code, then read it, don't just run grep! kre
Re: Missing documentation "-bash_input"
On Wednesday, November 29, 2023, Klaus Frank wrote: > One thing though, I probably should already know that, but why is a $0 > needed even though a command was already specified? Shouldn't the command > itself be $0? No, $0 is used in error messages: $ bash -c '"' foo foo: -c: line 1: unexpected EOF while looking for matching `"' $ You wouldn't want the entire script printed for every error. -- Oğuz
Re: Missing documentation "-bash_input"
On Wed, Nov 29, 2023 at 12:37:55AM +, Klaus Frank wrote: > One thing though, I probably should already know that, but why is a $0 > needed even though a command was already specified? Shouldn't the command > itself be $0? It's simply how sh -c has always worked. The first argument after -c is the script to be executed. The second argument after -c becomes $0 of the script, the third becomes $1, and so on. If you want to pass positional parameters to the -c script, therefore, you must put *something* in the slot between the script and the parameters. That something becomes $0. Common choices are sh, bash, _ and x but you can use pretty much any string.
Re: Missing documentation "-bash_input"
Hi, thanks for the explanation. Esp. the parsing one at the bottom, that explains why my tests were false positive. One thing though, I probably should already know that, but why is a $0 needed even though a command was already specified? Shouldn't the command itself be $0? On 2023-11-29 01:27:17, Lawrence Velázquez wrote: On Tue, Nov 28, 2023, at 5:33 PM, Klaus Frank wrote: sorry, but this is not true It is true. I can clearly see that it exists. It may be an distro addition though. Is it specific to ArchLinux? Because I can see it being used and when I try to use it on my system it also clearly works. You see it being used without causing errors, but that doesn't mean it's doing what you think it's doing. Observe that % bash -c 'printf %s\\n "$@"' -bash 1 2 3 and % bash -c 'printf %s\\n "$@"' --no_such_option 1 2 3 appear to behave identically. But against it just being a distro specific thing is that I also can see it within the bash source code mirror on GitHub. Where does it come from if it is not supposed to exist? Sorry, but something is really confusing here. Example usage: https://gitlab.archlinux.org/archlinux/devtools/-/blob/master/src/makechrootpkg.in?ref_type=heads#L152 arch-nspawn "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ bash -c 'yes y | pacman -U -- "$@"' -bash "${pkgnames[@]/#//root/}" You're misinterpreting that command line. As Andreas already explained, when you run something like bash -c 'command string here' a b c d the first argument after the command string (in my case "a", and in your case "-bash") is used as $0 while executing that command string, and the remaining arguments are used as the positional parameters. This happens even if an argument looks like an option, so options are not recognized as such if they follow -c [*]: % bash -x -c 'printf %s\\n "$0"' + printf '%s\n' bash bash % bash -c 'printf %s\\n "$0"' -x -x In your example, bash executes the command string 'yes ... "$@"' with "-bash" as $0 and the (possibly multiword) expansion of "${pkgnames[@]/#//root/}" as the positional parameter(s). I don't know why they are setting $0 to "-bash". Doing so makes the shell look like a login shell at a quick glance, but that doesn't make it one: % bash -c 'printf %s\\n "$0"; shopt login_shell' -bash -bash login_shell off --- [*]: Hypothetical "-bash" and "-bash_input" options would have to come before -c to take effect. However, bash does not use Tcl-style options, so "bash -bash" would be equivalent to "bash -b -a -s -h", and "bash -bash_input" to "bash -b -a -s -h -_ -i -n -p -u -t". These options all exist already except for "-_", which is why Greg's demonstration yielded the error "-_: invalid option". smime.p7s Description: S/MIME Cryptographic Signature
Re: Missing documentation "-bash_input"
On Tue, Nov 28, 2023, at 5:33 PM, Klaus Frank wrote: > sorry, but this is not true It is true. > I can clearly see that it exists. It may be > an distro addition though. Is it specific to ArchLinux? Because I can > see it being used and when I try to use it on my system it also clearly > works. You see it being used without causing errors, but that doesn't mean it's doing what you think it's doing. Observe that % bash -c 'printf %s\\n "$@"' -bash 1 2 3 and % bash -c 'printf %s\\n "$@"' --no_such_option 1 2 3 appear to behave identically. > But against it just being a distro specific thing is that I also > can see it within the bash source code mirror on GitHub. Where does it > come from if it is not supposed to exist? Sorry, but something is really > confusing here. > > > Example usage: > https://gitlab.archlinux.org/archlinux/devtools/-/blob/master/src/makechrootpkg.in?ref_type=heads#L152 > > arch-nspawn "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ > bash -c 'yes y | pacman -U -- "$@"' -bash "${pkgnames[@]/#//root/}" You're misinterpreting that command line. As Andreas already explained, when you run something like bash -c 'command string here' a b c d the first argument after the command string (in my case "a", and in your case "-bash") is used as $0 while executing that command string, and the remaining arguments are used as the positional parameters. This happens even if an argument looks like an option, so options are not recognized as such if they follow -c [*]: % bash -x -c 'printf %s\\n "$0"' + printf '%s\n' bash bash % bash -c 'printf %s\\n "$0"' -x -x In your example, bash executes the command string 'yes ... "$@"' with "-bash" as $0 and the (possibly multiword) expansion of "${pkgnames[@]/#//root/}" as the positional parameter(s). I don't know why they are setting $0 to "-bash". Doing so makes the shell look like a login shell at a quick glance, but that doesn't make it one: % bash -c 'printf %s\\n "$0"; shopt login_shell' -bash -bash login_shell off --- [*]: Hypothetical "-bash" and "-bash_input" options would have to come before -c to take effect. However, bash does not use Tcl-style options, so "bash -bash" would be equivalent to "bash -b -a -s -h", and "bash -bash_input" to "bash -b -a -s -h -_ -i -n -p -u -t". These options all exist already except for "-_", which is why Greg's demonstration yielded the error "-_: invalid option". -- vq
Re: Missing documentation "-bash_input"
On Tue, Nov 28, 2023 at 10:33:20PM +, Klaus Frank wrote: > sorry, but this is not true, I can clearly see that it exists. It may be an > distro addition though. Is it specific to ArchLinux? Here's what I get on Debian: unicorn:~$ bash -bash_input foobar -c 'read; declare -p REPLY' bash: -_: invalid option Usage: bash [GNU long option] [option] ... bash [GNU long option] [option] script-file ... GNU long options: --debug --debugger [...] I get the same thing if I use a bash that I compiled from upstream source. If I try --bash_input I get this: unicorn:~$ bash --bash_input foobar -c 'read; declare -p REPLY' bash: --bash_input: invalid option Usage: bash [GNU long option] [option] ... bash [GNU long option] [option] script-file ... GNU long options: --debug --debugger [...] > Bash source code on GitHub mirror: > https://github.com/bminor/bash/blob/master/y.tab.c#L3967 > > "(--bash_input.location.string) = c;" That's the pre-decrement operator in C. Here's the full context for that snippet: static int yy_string_unget (c) int c; { *(--bash_input.location.string) = c; return (c); } It's decreasing the value of bash_input by 1, before accessing it. It has nothing to do with the presence or absence of "--bash_input" or "-bash_input" as a command line argument.
Re: Missing documentation "-bash_input"
Hi, sorry, but this is not true, I can clearly see that it exists. It may be an distro addition though. Is it specific to ArchLinux? Because I can see it being used and when I try to use it on my system it also clearly works. But against it just being a distro specific thing is that I also can see it within the bash source code mirror on GitHub. Where does it come from if it is not supposed to exist? Sorry, but something is really confusing here. Example usage: https://gitlab.archlinux.org/archlinux/devtools/-/blob/master/src/makechrootpkg.in?ref_type=heads#L152 arch-nspawn "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ bash -c 'yes y | pacman -U -- "$@"' -bash "${pkgnames[@]/#//root/}" Bash source code on GitHub mirror: https://github.com/bminor/bash/blob/master/y.tab.c#L3967 "(--bash_input.location.string) = c;" Yours sincerely, Klaus Frank On 2023-11-28 15:30:20, Andreas Schwab wrote: On Nov 28 2023, Klaus Frank wrote: I just noticed that the man pages are missing documentation for the "-bash" (or better "-bash_input") parameter. There is no such thing as a -bash or -bash_input parameter. be better readable when being passed as an argument itself to e.g. nspawn or docker: `echo test1234 | bash -c "echo $@"`, `bash -c "echo $@" -bash "test1234"`, `bash -c "echo $@" -bash_input "test1234"`. The first argument passed after -c ... is just a placeholder here, it is used to set the $0 special parameter. $ bash -c 'echo $0 $2 $1' foo bar mumble foo mumble bar smime.p7s Description: S/MIME Cryptographic Signature
Re: bash crashes with segfault if LC_CTYPE or LC_ALL not set
On 11/28/23 11:16 AM, ra...@c.mail.sonic.net wrote: Bash crashes with a segfault, unless the variable LC_CTYPE or LC_ALL are set to a valid value (I have tried C, C.UTF-8, and en_US.UTF-8), before any "other" commands are executed. This was fixed by patch 2 to bash-5.2. -- ``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: [PATCH] OPTIND in funsub
On 11/28/23 1:14 AM, Grisha Levit wrote: If a funsub declares a local OPTIND, the calling context's getopts state gets messed up. Thanks for the reports and patches. Chet -- ``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/
bash crashes with segfault if LC_CTYPE or LC_ALL not set
Configuration Information [Manually overridden, the bug happened a while ago]: Machine: i386 (32-bit), also occurs on amd64 (64 bit) OS: freebsd12.3-RELEASE-p6 Compiler: cc Compilation CFLAGS: unknown, from a pre-built FreeBSD package uname output: FreeBSD house.lr.los-gatos.ca.us 12.3-RELEASE-p6 FreeBSD 12.3-RELEASE-p6 GENERIC i386 Machine Type: i386 (exact same problem occurs on a separate amd64 machine, same OS version) Bash Version: 5.2 Patch Level: 3 Release Status: release Description: Applies to bash 5.2_3. Problem did not exist on 5.1_16. Problem observed on FreeBSD 12.3-RELEASE-p6, on both architectures i386 and amd64. Problem started after upgrading bash. Using packages, not built from ports. Bash crashes with a segfault, unless the variable LC_CTYPE or LC_ALL are set to a valid value (I have tried C, C.UTF-8, and en_US.UTF-8), before any "other" commands are executed. So it works if you start it as "LC_CTPYE=C /usr/local/bin/bash", or it works if you have "LC_CTPYE=C" as the first executed line of .bashrc (and exactly equivalent with LC_ALL). By "first executed line" I mean the first first non-comment line. If LC_CTYPE is set to a syntactically valid but non-existing locale (for example "C.XXX-8" instead of UTF), and that setting is not an environment variable set when bash starts, but happens in the first line of .bashrc, then bash first prints an error message (and then segfaults): bash: warning: setlocale: LC_CTYPE: cannot change locale (C.XXX-8): Invalid argument What's the impact of this? If a system has users who use bash as their login shell, they become locked out. And in a fashion that's hard to debug, since the only indication that is left is an error message in /var/log/auth.log. More discussion can be found in the FreeBSD forum, with some traces that user _martin collected, can be found in here: https://forums.freebsd.org/threads/bash-is-broken-after-upgrade-to-5-2_3.86938/ Repeat-By: See above Fix: Temporary workaround: Add LC_CTYPE=... (something valid) as the first line of .bashrc for all users. Problem no longer exists in bash 5.2-15 running on FreeBSD 13.2, but I don't know where it was fixed.
Re: Missing documentation "-bash_input"
On Nov 28 2023, Klaus Frank wrote: > I just noticed that the man pages are missing documentation for the > "-bash" (or better "-bash_input") parameter. There is no such thing as a -bash or -bash_input parameter. > be better readable when being passed as an argument itself to e.g. nspawn > or docker: `echo test1234 | bash -c "echo $@"`, `bash -c "echo $@" -bash > "test1234"`, `bash -c "echo $@" -bash_input "test1234"`. The first argument passed after -c ... is just a placeholder here, it is used to set the $0 special parameter. $ bash -c 'echo $0 $2 $1' foo bar mumble foo mumble bar -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different."
Missing documentation "-bash_input"
Hi, I just noticed that the man pages are missing documentation for the "-bash" (or better "-bash_input") parameter. I just found the "-bash" parameter in a script and couldn't find any documentation about it, after checking out the source code I found "-bash_input" which after some testing is the code path "-bash" is somehow also pointing to. Could some documentation about this parameter be added to the man pages? It is defined in y.tab.c in line 3945 as part of yy_string_get and in code it is documented with "Let input come from STRING. STRING is zero terminated." meaning it uses the provided argument instead of stdin. Therefore these are equivalent but with the bash parameter it may be better readable when being passed as an argument itself to e.g. nspawn or docker: `echo test1234 | bash -c "echo $@"`, `bash -c "echo $@" -bash "test1234"`, `bash -c "echo $@" -bash_input "test1234"`. The section in the docs could be something like: ``` -bash_input, -bash: Can be used in scripts to provide pipe input to bash itself. This is especially useful when calling bash has to be wrapped within another command like chroot E.g. `chroot /path /bin/bash -c "echo $@" -bash "pipe input"` ``` Yours sincerely, Klaus Frank smime.p7s Description: S/MIME Cryptographic Signature