Process substitution in bash
- Published at
- Updated at
- Reading time
- 2min
Today I came across this little snippet of shell code bash <(curl -s https://codecov
. I found it in the documentation of Codecov, which is a code coverage tool mainly run in CI.
This "command structure" bash <(
was entirely new to me. So I dug a little bit.
What you see there is called process substitution, and the definition of it is as follow:
Process substitution allows a process’s input or output to be referred to using a filename.
Huh – that's interesting. So let's give this a try:
$ echo <(ls .)
/dev/fd/11
Okay, this is a file name. Let's try something else and look into the file using cat
.
$ cat <(ls .)
README.md
assets
...
...
Interesting! Looking into this file path shows the files printed by the ls
command.
Side note: I still have to dig what this /dev/fd
folder is used for because there are many interesting things such as stdout@
, stdin@
and stderr@
in there, but this is another topic.
How can you use process substitution then?
As you've seen, <(
lets you use the output of a command as a written file.
(thx to crater2150 for this understandable explanation on stack exchange)
Process substitution is handy if you want to "pipe" something into a command that doesn't understand UNIX pipes. The codecov example shows that a bash script is downloaded from https://codecov
, the content is written to a file and bash
executes this file. Pretty cool, hmm?
In a Node.js context, you can use it like this:
$ node <(echo 'console.log("foo")')
foo
But even more fantastic, you could use process substitution to execute stuff from your clipboard quickly. I'm on a Mac, which means I have the pbpaste
command available to run JavaScript code in my clipboard with a single command.
$ node <(pbpaste)
In short: process substitution allows you to skip temporary files and write some fancy one-liners. Sweet! 🎉
Join 5.5k readers and learn something new every week with Web Weekly.