Differences between revisions 4 and 5
Revision 4 as of 2012-01-19 18:18:29
Size: 3649
Editor: GreyCat
Comment: link to Environment
Revision 5 as of 2016-05-06 00:57:18
Size: 713
Editor: LavernT860
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
One of the fundamental concepts of shell programming is the '''subshell'''.

Every process on a Unix system has its own parcel of memory, for holding its variables, its file descriptors, its copy of the [[Environment]] inherited from its parent process, and so on. The changes to the variables (and other private information) in one process do not affect any other processes currently running on the system.

This becomes important when writing shell scripts, because so much of the work gets done by child processes of the script. There are obvious cases, like this:

{{{
#!/bin/sh
perl -e '$ENV{"foo"}="bar"; system "echo foo is \$foo"'
echo "$foo"
}}}

The perl program is run as a child of the shell, and therefore the change made to the environment variable `foo` by perl is seen only by perl's child process (the one invoked by `system`), but ''not'' by perl's parent process (our example script). However, that isn't what we generally mean by "subshell".

A subshell is a child process, like perl, but it's one that inherits more than a normal external command does. It can see all the variables of your script, not just the ones that have been exported to the environment; more on this below.

Here's an example of a forced subshell:
{{{
foo=old
(foo=bar)
echo "$foo"
}}}

The parentheses around the second command in the script force the command to be run in a subshell, and therefore the change it makes to variable `foo` is not seen by the main script.

This can be extremely useful. For example, you might want to suppress an environment variable temporarily:
{{{
(unset http_proxy; wget ...)
}}}

Or you might have a task that must run in a specific working directory, and you want the remainder of the script (or your interactive shell) ''not'' to be affected by that:

{{{
(cd /foo || exit 1; tar ...)
}}}

Subshells can also be a pitfall for the unwary. There are many instances in which a shell creates a subshell without parentheses being placed by the programmer. The most common ones are pipelines, and command substitutions. First, the pipeline:
{{{
echo hello | read a
echo "$a"
}}}

In this example, the variable `a` is assigned a value by `read`, but only in its own process. If we're in a Bourne shell, a POSIX shell, pdksh, or Bash, the `read` takes place in a subshell (because every command in a pipeline is run in its own subshell), and therefore the variable `a` in the main script is unaffected.

However, in ksh88 or ksh93, the last command in a pipeline is ''not'' run in a subshell. In those shells, the example above would cause the variable `a` in the main script to hold the value `hello`.

[[CommandSubstitution|Command substitution]] is usually a problem only when it's combined with functions. For example,
{{{
f() {
  count=$(($count+1))
  echo something
}
count=0
value=$(f)
echo "$count"
}}}

The global variable `count` is incremented whenever function `f` is called. However, when `f` is called in a ''command substitution'' as shown above, the function runs in a subshell. This means, as I'm sure you've guessed by now, the counter does not get incremented in the main part of the script.

For workarounds to these sorts of problems, see [[BashFAQ/024|Bash FAQ #24]].

For an example of the difference between a subshell and a child process that happens to be a shell:
{{{
unset a; a=1
(echo "a is $a in the subshell")
sh -c 'echo "a is $a in the child shell"'
}}}

In the subshell, the regular shell variable `a` is visible; but because it is not exported, the full child process does not see it.

----
CategoryShell
Yun may be the label with even though it is not the title on my birth certificate, I really like to become named She's considering [[http://Www.becomegorgeous.com/topics/additional%20options|additional options]] although she's always loved surviving in American Samoa nevertheless To [[http://www.caringbridge.org/search?q=enjoy%20chess|enjoy chess]] is a thing that she is been doing for years. Scheduling vacations is she makes an income Read the latest news on my website: http://Www.Vallidilanzoeventi.it/component/k2/itemlist/user/802204.html<<BR>><<BR>>
<<BR>><<BR>>
Here is my page :: [[http://Www.Vallidilanzoeventi.it/component/k2/itemlist/user/802204.html|dr amend's pheromone advantage review]]

Yun may be the label with even though it is not the title on my birth certificate, I really like to become named She's considering additional options although she's always loved surviving in American Samoa nevertheless To enjoy chess is a thing that she is been doing for years. Scheduling vacations is she makes an income Read the latest news on my website: http://Www.Vallidilanzoeventi.it/component/k2/itemlist/user/802204.html<<BR>><<BR>>

Here is my page :: dr amend's pheromone advantage review

SubShell (last edited 2020-03-10 17:21:49 by intranet)