Does a Shell function run in a sub-shell?

Viewed 8829

I'm trying to get around a problem that seems to me you cannot pass open db2 connection to a sub-shell.

My code organization is as follows:

Driver script (in my_driver.sh)

# foo.sh defines baz() bar(), which use a db2 connection
# Also the "$param_file" is set in foo.sh!
source foo.sh

db2 "connect to $dbName USER $dbUser using $dbPass"

function doit
{
    cat $param_file | while read params
    do
        baz $params
        bar $params
    done
}

doit

I've simplified my code, but the above is enough the give the idea. I start the above:

my_driver.sh

Now, my real issue is that the db2 connection is not available in sub-shell:

I tried:

. my_driver.sh

Does not help

If I do it manually from the command line:

source foo.sh

And I set $params manually:

baz $params
bar $params

Then it does work! So it seems that doit or something else acts as if bar and baz are executed from a sub-shell.

I would be elated if I can somehow figure out how to pass db2 open connection to sub-shell would be best.

Otherwise, these shell functions seem to me that they run in a sub-shell. Is there a way around that?

3 Answers

A shell function in such shells as sh (i.e. Dash) or Bash may be considered as a labelled commands group or named "code block" which may be called multiple times by its name. A command group surrounded by {} does not create a subshell or "fork" a process, but executes in the same process and environment.

Some might find it relatively similar to goto where function names represent labels as in other programming languages, including C, Basic, or Assembler. However, the statements vary quite greatly (e.g. functions return, but goto - doesn't) and Go To Statement may be Considered Harmful.


Shell Functions

Shell functions are a way to group commands for later execution using a single name for the group. They are executed just like a "regular" command. When the name of a shell function is used as a simple command name, the list of commands associated with that function name is executed. Shell functions are executed in the current shell context; no new process is created to interpret them.

Functions are declared using this syntax:

fname () compound-command [ redirections ]

or

function fname [()] compound-command [ redirections ]

This defines a shell function named fname. The reserved word function is optional. If the function reserved word is supplied, the parentheses are optional.

Source: https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html or man bash.

Grouping Commands Together

Commands may be grouped by writing either

(list)

or

{ list; }

The first of these executes the commands in a subshell. Builtin commands grouped into a (list) will not affect the current shell. The second form does not fork another shell so is slightly more efficient. Grouping commands together this way allows you to redirect their output as though they were one program:

{ printf " hello " ; printf " world\n" ; } > greeting

Note that "}" must follow a control operator (here, ";") so that it is recognized as a reserved word and not as another command argument.

Functions

The syntax of a function definition is

name () command

A function definition is an executable statement; when executed it installs a function named name and returns an exit status of zero. The command is normally a list enclosed between "{" and "}".

Source: https://linux.die.net/man/1/dash or man sh.

Transfers control unconditionally.

Used when it is otherwise impossible to transfer control to the desired location using other statements... The goto statement transfers control to the location specified by label. The goto statement must be in the same function as the label it is referring, it may appear before or after the label.

Source: https://en.cppreference.com/w/cpp/language/goto

Goto

... It performs a one-way transfer of control to another line of code; in contrast a function call normally returns control. The jumped-to locations are usually identified using labels, though some languages use line numbers. At the machine code level, a goto is a form of branch or jump statement, in some cases combined with a stack adjustment. Many languages support the goto statement, and many do not...

Source: https://en.wikipedia.org/wiki/Goto


Related:
https://mywiki.wooledge.org/BashProgramming#Functions
https://uomresearchit.github.io/shell-programming-course/04-subshells_and_functions/index.html (Subshells and Functions...)
Is there a "goto" statement in bash?
What's the difference between "call" and "invoke"?
https://en.wikipedia.org/wiki/Call_stack
https://mywiki.wooledge.org/BashPitfalls

Related