• Uncategorized

About linux : Shell-local-variable-in-forked-process-linux-closed

Question Detail

I have read that a forked child process gets its environment (such as env variables) inherited from the parent process. It is also said that local shell variables are not available to the forked child processes, but if that is the case how can a local variable defined in a shell be echoed by its child process (echo in this case)? as echo is the child process of the shell.

Question Answer

I have read that a forked child process gets its environment (such as env variables) inherited from the parent process.

Not “such as”. In that sense of the word “environment”, the environment consists of environment variable names and values only. There as a larger, more inclusive execution context for each process, but its “environment” is just a set of variables.

It is also said that local shell variables are not available to the forked child processes

You clarified in comments on the question that by “local shell variables” you mean variables that are not marked for export. Yes, by definition, these are not provided to child processes.

if that is the case how can a local variable defined in a shell be echoed by its child process (echo in this case)? as echo is the child process of the shell.

It can’t and doesn’t, because echo doesn’t do that. By which I mean, it does nothing with any environment variables inherited from its parent process.

I guess you must be asking about something like this:

# not exported:
foo=something

echo "$foo"

, which will print “something” followed by a newline. But that does not rely on variable foo being exported to the process in which echo runs. Rather, the shell expands the variable reference as part of a larger collection of expansions that it performs on each command before executing it. The child process receives a literal something as its argument.

To further elucidate, try this:

foo=something

bash -c "echo $foo"
bash -c 'echo $foo'

The output is one “something” and one blank line. Why? Because the parent shell expands the variable reference inside double quotes, but not the one in single quotes. In neither case does the child bash process receive variable foo in its environment, but in the first case it does not need it, because by the time that process receives it, the command string it is asked to execute has no reference to $foo. The same is not true in the second case.

Child processes get a copy of their parents’ environment. They can see all the exported environment variables and even modify them, but those modifications won’t be seen by the parent.

Variable set in parent visible in child:

$ export foo=bar
$ echo "parent: $foo"
parent: bar
$ (echo "child: $foo")
child: bar

Modification in child not visible in parent:

$ (foo=baz; echo "child: $foo")
child: baz
$ echo "parent: $foo"
parent: bar

If you don’t export a variable then it is only a shell variable and not part of the environment. In that case you can see the variable in a subshell since subshells are special cased:

$ foo=bar
$ (echo "child: $foo")
child: bar

However if you create a child process via any other mechanism, such as by explicitly invoking bash, it won’t be visible since it’s not part of the environment and doesn’t survive the fork:

$ foo=bar
$ bash -c 'echo "child: $foo"'
child: 

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.