13
echo hello | read str
echo $str

This read is executed after the pipeline, which means that the output of the echo gets read into str - but because it is after a pipe, the contents of str are now in a subshell that cannot be read by the parent shell.

What happens in to the contents of str? Does the pipe create a subshell, and then once the content are read into str, does the parent process kill the child process and str is erased - or does the contents of str live on somewhere outside the shell? Like how do we see what is in the subshells? Can we access subshells from the parent shells?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
capser
  • 2,442
  • 5
  • 42
  • 74

2 Answers2

12

The value of ${str} only exists during the lifetime of the subshell. Whether the left or right side of the pipe will be parent or subshell depends on the specific shell and the shell version.

Bash 4.x has an option shopt -s lastpipe to run the last command of a pipeline in the parent shell, like ksh93 does by default. The value of $str will then persist.

Henk Langeveld
  • 8,088
  • 1
  • 43
  • 57
11

In your example, $str exists inside a subshell and by default, it disappears once the line has finished. A child process cannot modify its parent.

Aside from changing the shell option lastpipe, you can also change the code to avoid using a pipe. In this case, you could use:

read str < <(your command) 
# or
str=$(your command)

Both of these create subshells too, but $str is assigned to in the parent process.

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141