Pages

Saturday, 12 December 2020

When read meets pipe --- another bash trick

Today I came across another trick of bash.

[smstong@mk8 ~]$ echo hello | read x
[smstong@mk8 ~]$ echo $x

[smstong@mk8 ~]$

What I wanted to do is set variable x to a value of "hello". But actually, x is not set at all!

1 Root cause

Bash will start a new subshell when seeing a pipe sign. That means, the "read x" ran in a subshell.
As a result, the variable "x" was set in that subshell's process rather than the interactive shell process. This is clear in the below example.

[smstong@mk8 ~]$ echo hello | (read x; echo $x)
hello

2 Solution

As child processes are not able to set variables in their parent process, "read x" cannot work with pipes.
We have to let "read x" run in the current shell process.

Use $() instead.

[smstong@mk8 ~]$ x=$(echo hello)
[smstong@mk8 ~]$ echo $x
hello


No comments:

Post a Comment