Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash piping prevents global variable assignment

unset v
function f {
  v=1
}
f | cat
echo v=$v
f 
echo v=$v

Why does piping (to any command) prevent the first echo command from printing 1? The second echo prints 1. I'm using a bash shell. I can see this by copy/paste or by running this as a script.

like image 937
jcalfee314 Avatar asked Jun 06 '11 16:06

jcalfee314


People also ask

Do Bash functions have access to global variables?

By default, every variable in bash is global to every function, script and even the outside shell if you are declaring your variables inside a script.

What does piping to Bash do?

A pipe in Bash takes the standard output of one process and passes it as standard input into another process. Bash scripts support positional arguments that can be passed in at the command line.

How do you set a global variable in Bash?

The easiest way to set environment variables in Bash is to use the “export” keyword followed by the variable name, an equal sign and the value to be assigned to the environment variable.

Can you assign variables in Bash?

A variable in bash can contain a number, a character, a string of characters. You have no need to declare a variable, just assigning a value to its reference will create it.


1 Answers

All components of a pipeline (if more than one) are executed in a subshell, and their variable assignments do not persist to the main shell.

The reason for this is that bash does not support real multithreading (with concurrent access to variables), only subprocesses which run in parallel.


How to avoid this:

You have to do any variable assignments you want to retain in the main bash process (or find some way to transfer them there). The bash way of doing this would be not to use a pipe, but use process substitution instead:

f > >( cat )

Of course, this will not help if you need to do variable assignments in both processes of a pipe. Then you have to think of a better mechanism instead (maybe coprocesses, and output the variables somewhere?)

like image 138
Paŭlo Ebermann Avatar answered Oct 14 '22 10:10

Paŭlo Ebermann