0

If I execute the following command:

> read someVariable _ < <(echo "54 41")

and:

> echo $someVariable

The result is: 54.

What does < < (with spaces) do?

Why is _ giving the first word from the result in the "echo" command?

The commands above are just example.

Thanks a lot

3
  • Please show the output of read someVariable _ < <(echo "54 41") ; echo "$_" Commented Feb 24, 2019 at 6:00
  • read var1 var2 sets var1 to the first "word" of input, and var2 to the second "word". So read someVariable _ sets someVariable to the first "word" (in this case "54"), and a variable named underscore to the second "word" ("41"). Commented Feb 24, 2019 at 8:48
  • Thanks @GordonDavisson. greetings.- Commented Feb 25, 2019 at 14:12

1 Answer 1

1

Process Substitution

As tldp.org explains,

Process substitution feeds the output of a process (or processes) into the stdin of another process.

So in effect this is similar to piping stdout of one command to the other , e.g. echo foobar barfoo | wc . But notice: in the [bash manpage][3] you will see that it is denoted as <(list). So basically you can redirect output of multiple (!) commands.

Note: technically when you say < < you aren't referring to one thing, but two redirection with single < and process redirection of output from <( . . .).

Now what happens if we do just process substitution?

$ echo <(echo bar)
/dev/fd/63

As you can see, the shell creates temporary file descriptor /dev/fd/63 where the output goes. That means < redirects that file descriptor as input into a command.

So very simple example would be to make process substitution of output from two echo commands into wc:

$ wc < <(echo bar;echo foo)
      2       2       8

So here we make shell create a file descriptor for all the output that happens in the parenthesis and redirect that as input to wc .As expected, wc receives that stream from two echo commands, which by itself would output two lines, each having a word, and appropriately we have 2 words, 2 lines, and 6 characters plus two newlines counted.

Side Note: Process substitution may be referred to as a bashism (a command or structure usable in advanced shells like bash, but not specified by POSIX), but it was implemented in ksh before bash's existence as ksh man page. Shells like tcsh and mksh however do not have process substitution. So how could we go around redirecting output of multiple commands into another command without process substitution? Grouping plus piping!

$ (echo foo;echo bar) | wc
      2       2       8

Effectively this is the same as above example, However, this is different under the hood from process substitution, since we make stdout of the whole subshell and stdin of wc [linked with the pipe][5]. On the other hand, process substitution makes a command read a temporary file descriptor.

So if we can do grouping with piping, why do we need process substitution? Because sometimes we cannot use piping. Consider the example below - comparing outputs of two commands with diff (which needs two files, and in this case we are giving it two file descriptors)

diff <(ls /bin) <(ls /usr/bin)
Sign up to request clarification or add additional context in comments.

2 Comments

For completeness, note that the creation of /dev/fd/63 is an implementation detail of process substitution. A different implementation of bash (for a platform without /dev/fd, for example) might used named pipes instead. echo <(echo bar) in that case might output something like /tmp/fifo1, if bash created a named pipe called fifo1 in the /tmp directory.
thanks a lot Aman Gupta; now is more clear the concept. also Thank you for your contribution @chepner.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.