DEV Community

Cover image for A little-known Linux feature - Process Substitution
Elena
Elena

Posted on

A little-known Linux feature - Process Substitution

The first time I ever entered a Linux command was when I was doing The Odin Project, it was confusing to picture how to do actions you do with a GUI in a blank window you hope that somehow starts to enter commands on its own

After a bit of time of me staring at that cursor and it staring back at me I learned quite a few commands. File system navigation, searching for file permissions, etc. Thought I knew it all but I, in fact, didn't

So what other commands and topics was I missing?

Well too many, maybe still too many actually. I wanted to write about at least one topic about Linux so I chose Process Substitution since for some reasons so very few people mention it

So, what's that?

First of all it's called like this because you are substituting a normal file name with the output of a process (a command) that gets put in a temporary file

I think the best way to explain it is actually through an example (a very useless one also does the job)
Let's say you want to do this:

echo hello > file1
echo world > file2
cat file1 file2
Enter fullscreen mode Exit fullscreen mode

I redirect "hello" to the first file and "world" to the second one, then I read the output of both:

hello
world
Enter fullscreen mode Exit fullscreen mode

Pretty straightforward, right?
Now I'll tell you that you can do the same thing with just one line

cat <(echo hello) <(echo world)
Enter fullscreen mode Exit fullscreen mode

Well, I'm still redirecting the output "somewhere" before reading them with cat, just not a normal file. They get redirected to something called a "pipe" which you can imagine like a virtual file that doesn't get saved and gets destroyed the moment the process ends. These "files" (e.g. /dev/fd/63) hold the output and pass them to cat which does its simple and repetitive job

A feature that lets you treat a command (usually its output) as a temporary file to give to another (main) command

is the way I like to think about it. Other definitions confuse me

The post could end here BUT I'd like to go a bit deeper and I'd like to make some other (more difficult and maybe useful) examples

Input Substitution & Output Substitution

  • <(...) this is what we've used in the example, takes the output of a file, puts it into a temporary file and feeds it to the main command

  • >(...) this does the opposite, the output of the main command goes into this. I'll make an example

Output substitution

Let's say we have three files that we'll call main_output, copy1 and copy2 (since I'm very creative with names). Main output is a file with lines and some of them begin with either "First file" or "Second file". Our goal is to send lines that begin with (or contain) "First file" to the file "copy1" and the lines that begin with (or contain) "Second file" to the file "copy2"

cat main_output >(grep "First file" > copy1) >(grep "Second file" > copy2)
Enter fullscreen mode Exit fullscreen mode

As easy as that. No I'm kidding, this is wrong. Don't do that. Cat doesn't even know what to do if you tell it to write something

tee - correction of the previous example

cat main_output | tee >(grep "First file" > copy1) >(grep "Second file" > copy2)
Enter fullscreen mode Exit fullscreen mode

"Tee intercepts the pipe stream and saves a copy of the data"
This is what I've written in my notes (probably copied somewhere). Just a fancy way to say it splits the stream and gives data to both

Split-piping

Now... let's say that you want to send the output and errors of a script to two different scripts

./script > >(bash output_script) 2> >(bash error_script)
Enter fullscreen mode Exit fullscreen mode
  • > (or 1>) redirects stdout to the "output_script"

  • 2 > redirects stderr to the "error_script"


I think that's all, and how they say it "use it or flex it", or maybe it wasn't like this, whatever.

Top comments (0)