Yes, but I have always found that cumbersome and I was never sure which program has which pipe, and what will exactly happen if one of the reading/writing programs dies. (I am still not sure.)
One thing to keep in mind is that if nothing ever consumes the data in the pipe, the pipe stays around and you eventually will run out of open file descriptors. So if you're scripting with named pipes, be sure you have adequate cleanup in case of errors.
True. I've known about that feature of bash, but I have found precious few good opportunities to use it. As someone mentioned below, if a program expects a file and you give it a pipe, it may try to seek and cause the whole thing to fail. So trying to use it is always a gamble. Moreover, a named pipe is an object in the filesystem that bash has to create, only to remove it a moment later. So it is not really any cleaner than using a temp file. The only case where you'd clearly benefit is when the amount of data is too big to justify temporarily writing it out to a file.
bash doesn't create named pipe filesystem objects when you use process substitution, it passes file descriptors via the dynamically created kernel managed /dev/fd paths. There is nothing to clean up.
Oh, I think I see what you're saying. So calling them named pipes is inaccurate, then. If I'm not mistaken, using features of the /dev filesystem would be dependent on Linux, then. Either way, it isn't really a very robust design. Not like a pipe returned by pipe(2) and passed to a program that is expecting it. Simple unnamed pipes are a fundamental part of unix.
Here's what the man page says:
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of
naming open files. It takes the form of <(list) or >(list). The process list is run with its input or
output connected to a FIFO or some file in /dev/fd. The name of this file is passed as an argument to
the current command as the result of the expansion. If the >(list) form is used, writing to the file
will provide input for list. If the <(list) form is used, the file passed as an argument should be read
to obtain the output of list.
So it's done with /dev/fd if that's available, which basically means Linux with that filesystem mounted. Otherwise it falls back on named pipes.
Future readers, #bash on freenode says of this link:
< greybot> The infamous "Advanced" Bash Scripting Guide should be avoided unless you know how to filter out the junk. It will teach you to write bugs, not scripts. In that light, the BashGuide was written: http://mywiki.wooledge.org/BashGuide
They felt strongly enough to learn their bot of it. Keep this in mind, I haven't read much of either resource yet.
Interesting. I'd not heard anything negative about it, and found it useful both in my day-to-day BASH-ing and in a position where I maintained a huge pile of BASH scripts. It may very well be that I knew how to filter out the junk. There is certainly a lot that doesn't belong in scripts but is quite useful interactively.
Why, that's exactly what it is? It's a named pipe, but not one used explicitly by you but implicitly by the process substitution feature to pass a file, which of course has a name, to another process. It's only anonymous to you because you didn't name it, to the system it's an ordinary named pipe.
Anonymous in that their name doesn't matter and you need not care about it. They are implemented using pipes with actual names, but the names aren't important from the shell user's point of view.
Related: anybody has ideas to achieve the following?
display the stdout of a program on the console and also write a gzipped version of stdout to a file.
I currently jump through some hoops (involving two term windows) to achieve. 'tee -a' to a named pipe in one window and in another window, 'gzip <' from that named pipe. Would prefer a single-window, single-command solution.
Very useful, hopefully I remember this when I need it next time (that being the bane of all bash cleverness). The >(foo) would benefit from some extra explanation though, currently it is not very clear how it differs from regular |foo.
>(foo) turns into a file name, so it can be passed to things that absolutely want a file name to write to. And multiple occurrences of this should work as you'd expect.
Basically a builtin for `true`. Its use in forkbombs is unrelated except for the fact that it's a valid character in a bash function name. Defining `:(){:|:&)` obviously shadows the builtin.