Alan D. Salewski via plug on 4 May 2023 20:29:13 -0700


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] take-your-bash-scripting-seriously


On Thu, May 4, 2023, at 18:42, Ron Mansolino via plug wrote:
> Some notes on cross-platform compatibility (a bit of /bin/sh rant):
> https://medium.com/@jesse_62134/take-your-bash-scripting-seriously-198778c68ba5

Thanks for the link. I love that it references an article by Larry
Wall -- always an insightful and entertaining read.


> Mention of the size of the bash binary has me wondering:
> If my script loads a few other scripts that expressly declare bash up top,
> does one interpreter run them all?
> (or does each one spawn a new bash process?)

It depends on what you mean by "loads a few other scripts".

If you "source" those other scripts via the builtin 'source' command
(a.k.a. '.'), then the sourced script executes in the context of the
current process -- as if the lines from the other script existed at
the point of the 'source' statement. That does not create a new
subprocess.

If you simply invoke a those other scripts by name, then each runs
in a separate subprocess of the current bash process.

If you use the builtin 'exec' command to run a script, it replaces
the current bash process.


> I got in the habit of not specifying bash unless I have to, if these
> scripts don't specify bash, do _they_ all run in the same environment?
> (I don't 'get' how the environment is passed around and I've been bit by
> variables that I expected that weren't exported (?)

Whether you specify bash or not does not matter: each script
invocation will be run in a separate subprocess unless using
'source' or 'exec' as outlined above.

Which shell interpreter will be used depends on the "shebang
line". If the first line says #/bin/bash, then the file content will
be provided to the /bin/bash executable to run. If the first line
says #/bin/sh, then the file content will be provided to the /bin/sh
executable (which may be bash, dash, or something else). If it
happens to be bash, it will behave differently than if /bin/bash had
been specified; specifically:

<quote src="bash(1)">
    If bash is invoked with the name sh, it tries to mimic the
    startup behavior of historical versions of sh as closely as
    possible, while conforming to the POSIX standard as well.
</quote>

If the script file is readable and executable, but does not have a
shebang line at all, then traditional Bourne-like shells will
typically run the script with /bin/sh. Bash will run the script with
bash.[0]

The main thing to understand is that in Unix and Linux, processes
exist in a tree. The first process started at system startup time
gets PID 1, and all other processes that run on the system are
descendants (either directly or indirectly) from that first process.

Each process has some memory area of its own, and included in this
is the command line arguments with which it was invoked, and a list
of name and value pairs known as the "environment".

When a new process is created, the process from which it is forked
has some control over the characteristics of the new
subprocess. Among those are the name and value pairs in the
environment -- hence the name "environment variables".

When bash is creating a subprocess, it controls which environment
variables to include in the subprocess. Only variables in the
current bash process that have been explicitly "exported" will be
present in the newly created subprocess. Hence:

    FOO='this-is-not-exported'

    declare -x BAR='this-is-exported'

    export BAZ='this-is-exported-too'

    QUUX='this-will-be-exported-by-the-next-line'
    export QUUX


> Tcsh,
> Ron

HTH,
-Al


[0] To see it in action:

    $ printf '%s\n' 'echo this is blahblah' 'ps --forest' > ./blahblah

    $ chmod u+x ./blahblah

    When run with bash, you get:
    
    $ ./blahblah
    this is blahblah
      PID TTY          TIME CMD
    11435 pts/224  00:00:00 bash
    20605 pts/224  00:00:00  \_ bash
    20606 pts/224  00:00:00      \_ ps

    When run with dash, you get:

    $ ./blahblah
    this is blahblah
      PID TTY          TIME CMD
    11435 pts/224  00:00:00 bash
    21741 pts/224  00:00:00  \_ dash
    21844 pts/224  00:00:00      \_ sh
    21845 pts/224  00:00:00          \_ ps


-- 
a l a n   d.   s a l e w s k i
ads@salewski.email
salewski@att.net
https://github.com/salewski
___________________________________________________________________________
Philadelphia Linux Users Group         --        http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug