Re: Missing documentation "-bash_input"

2023-11-28 Thread Robert Elz
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"

2023-11-28 Thread Oğuz
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"

2023-11-28 Thread Greg Wooledge
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"

2023-11-28 Thread Klaus Frank

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"

2023-11-28 Thread Lawrence Velázquez
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"

2023-11-28 Thread Greg Wooledge
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"

2023-11-28 Thread Klaus Frank

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

2023-11-28 Thread Chet Ramey

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

2023-11-28 Thread Chet Ramey

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

2023-11-28 Thread ralph
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"

2023-11-28 Thread Andreas Schwab
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"

2023-11-28 Thread Klaus Frank

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