top | item 6705999

Named Pipes in Bash

88 points| nkurz | 12 years ago |hollenback.net

34 comments

order
[+] pstadler|12 years ago|reply
You can create named pipes explicitly:

    $ mkfifo ~/pipe
    $ ./background.sh > ~/pipe &
    $ tail -f ~/pipe
http://www.linuxjournal.com/article/2156
[+] runn1ng|12 years ago|reply
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.)

So I am glad that what OP wrote exists.

[+] saljam|12 years ago|reply
There's a caveat with process substitution; the command can't seek() on the input file.

If if a command, for example, needs to do 2 passes, it'll will either have to be 'smart' enough to stick the output in a buffer or fail.

[+] eatitraw|12 years ago|reply
Yes, this is a problem in bash. In zsh you can use temporary files for process substitution, like this:

vimdiff =(ls /bin) =(ls /usr/bin)

You can use it even from bash:

zsh -c 'vimdiff =(ls /bin) =(ls /usr/bin)'

[+] dllthomas|12 years ago|reply
This and so much more is in http://www.tldp.org/LDP/abs/html - well worth perusing if you're needing to do a lot of bash.
[+] recuter|12 years ago|reply
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.

[+] perlgeek|12 years ago|reply
Are these really named pipes? And if yes, what are the names? Kinda looks like anonymous pipes to my untrained eyes.
[+] gnaritas|12 years ago|reply
They're anonymous named pipes. Do this in a shell to see the name:

    echo <(true)
[+] taway2012|12 years ago|reply
Pretty cool.

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.

[+] ColinWright|12 years ago|reply
What's wrong with:

    cmd | tee >( gzip - > cmd.out.gz )
[+] runejuhl|12 years ago|reply
Something like this?

    ls -al | tee >(cat) | gzip -c
[+] _paulc|12 years ago|reply
ls -al | gzip -c | tee out.gz | gzip -dc
[+] zokier|12 years ago|reply
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.
[+] bartbes|12 years ago|reply
>(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.
[+] kps|12 years ago|reply
This 'bash' feature, among others, was in ksh before bash existed.
[+] panzi|12 years ago|reply
If I would have seen this one or two hours ago it could have spared me hate on irc://irc.freenode.net/bash