Re: 'exec -a' and $0 substitution
On Thu, 26 Jan 2023 00:35:27 -0500 Lawrence Velázquez wrote: > On Wed, Jan 25, 2023, at 6:37 PM, Sergei Trofimovich wrote: > > I fear it's a side-effect of the way 'bash' gets executed via shebang by > > kernel. But maybe not? Somehow direct script execution still manages to > > preserve script's name. Is it an intended behaviour that could not be > > easily changed? Or it's a bug? > > It's not a bug. Thank you! That will make generic wrapping a bit more involved for us. > https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html#index-0 > > 0 > ($0) Expands to the name of the shell or shell > script. This is set at shell initialization. If > Bash is invoked with a file of commands (see Shell > Scripts), $0 is set to the name of that file. If > Bash is started with the -c option (see Invoking > Bash), then $0 is set to the first argument after > the string to be executed, if one is present. > Otherwise, it is set to the filename used to invoke > Bash, as given by argument zero. > > Whenever bash is executed with a script file, it sets $0 to the > name of that file. It only uses caller-provided values for $0 when > a script file is not provided. > > $ (exec -a foo bash <<<'echo "$0"') > foo > $ (exec -a foo bash -s bar baz quux <<<'echo "$0"') > foo > $ (exec -a foo bash -c 'echo "$0"') > foo > $ (exec -a foo bash -c 'echo "$0"' bar baz quux) > bar > > This behavior is standardized in POSIX [*] and is not unique to > bash (I omitted ksh93, which actually does produce "foo" here). > > $ (exec -a foo zsh <(echo 'echo "$0"')) > /dev/fd/63 > $ (exec -a foo dash <(echo 'echo "$0"')) > /dev/fd/63 > $ (exec -a foo yash <(echo 'echo "$0"')) > /dev/fd/63 > $ (exec -a foo mksh <(echo 'echo "$0"')) > /dev/fd/63 > > [*]: > https://pubs.opengroup.org/onlinepubs/9699919799/utilities/sh.html#tag_20_117_05 > > -- > vq -- Sergei
Re: More convenient tracing
Greg Wooledge writes: > On Wed, Jan 25, 2023 at 03:00:27PM -0500, Dale R. Worley wrote: >> >> Tracing with -x prints a lot of (usually) useless lines. >> >> $ bash -x ./tt >> [300+ lines of Bash initializations] >> + echo 'Now in tt.' >> Now in tt. > > Why does it do this? Have you got BASH_ENV set to something in your > environment? I do have BASH_ENV set, to ~/.bashrc. I need that so that my scripts can use my .bashrc customizations. Though I do know that I haven't gotten the Bash startup scripts set correctly for the effects I want; fixing that would cut most but by no means all of the "Bash initializations" listed above. Dale
Re: More convenient tracing
On Thu, Jan 26, 2023 at 12:03:08PM -0500, Dale R. Worley wrote: > I do have BASH_ENV set, to ~/.bashrc. I need that so that my scripts > can use my .bashrc customizations. I strongly advise against this. All of the things a script does should be discoverable by reading the script, and any files that are explicitly dotted in (sourced) by that script. There shouldn't be any surprises coming in from the execution environment. If your script needs external variables, it should explicitly dot in a file that sets just those variables. (Usually, /etc/default/ or ~/.config/ contains files of this type.) Such a file should NOT be a user's .bashrc because that can change on a whim, and may do things that the script would neither expect nor desire.
Re: 'exec -a' and $0 substitution
On Thu, 26 Jan 2023, 09:37 Sergei Trofimovich, wrote: > To the bug: looks like 'exec -a' does not work for bash scripts, but does > work for other executables. > Be aware that the kernel is responsible for interpreting #! lines, not bash. The kernel does several steps when it encounters an executable that starts with the bytes '#' and '!'. 1. replacing argv[0] with the exec path, and 2. read bytes up to the first newline, skipping leading and trailing whitespace; 3. if interstitial whitespace is present, split into two words at the first run of whitespace 4. push these latter strings onto the front of argv 5. replace the exec path with a copy of (the new) argb[0] 6. re-start the execve procedure Failing to make the substitution in step 1 would leave the interpreter running but with no idea how to open the script so that it could run it. -Martin >