In one shell:
mplayer -input file=named_pipe
In a different shell:
echo 'pause' > named_pipe
or:
echo 'quit' > named_pipe
So you can control your music player easily. (I bind the echo script to hotkeys.)
Example 2:
mysql LOAD DATA INFILE wants a filename. So I made a named pipe and sent my data there (putting that command in the background since it will hang till the data is read). Then I use that named pipe as the filename for load data.
Example 3:
You want to send your data over ssh, but you also want to send commands over ssh (you can't do both at the same time, except in the command line which might not be enough). You could send the data over a second ssh session - but then you can't do your preliminary commands first.
So you make a named pipe on the server and send the data to it in one ssh session. Then you open a second ssh session, do your preliminary commands, then your data command using the named pipe as a filename.
(There are other ways to do this with renaming file descriptors in a shell, but a named pipe is easier, and much more flexible.)
Example 4:
You want to start a long running process that waits for data. You let it read from the named pipe, and then you can write to the named pipe from any other program as needed.
SSH already has a Control facility for this.
The Control facility is for multiplexing the data streams, but that solves a different problem.
So, I set up a FIFO like described, and then I bound the key '1' in Emacs to echo 'p' to it. Voila. I could seamlessly pause and unpause the video while typing away furiously. The strategy was quite a hack, but it worked very well for my purpose.
Having said that, I have had occasion to use named pipes in a shell script. Basically, I had two programs and I wanted to determine which lines were in one, but not both, of their outputs. Using named pipes, I was able to do something like:
mkfifo foo
./prog1 > foo &
./prog2 > foo &
cat foo | sort | uniq -u
Effectively, this provides a way to combine the output of multiple commands. I took it as a matter of faith that doing this won't interleave lines. I assume that as long as both programs flush only at line breaks then there is not any problem. sort < foo | uniq -u
not work with named pipes?The advantage to
cat foo | sort | uniq -u
is that it is (marginally) easier to drop in another filter in front of sort. <foo sort | uniq -u
(redirections can be at the beginning too.)Also: sort -u instead of sort|uniq.
{ ./prog1; ./prog2; } | sort | uniq -u
IIRC, they're guaranteed not to interleave write()s less than PIPE_BUF (4k?) but if your program is buffering internally it might not end writes on a newline.
mkfifo file; script -f file
Other user simply does cat file mkfifo split_aa
mkfifo split_ab
mkfifo sorted_aa
mkfifo sorted_ab
split -n2 input_file split_ &
sort split_aa >> sorted_aa &
sort split_ab >> sorted_ab &
sort -m sorted_aa sorted_bb > final_sorted
It's left as an exercise for the reader to determine if this actually saves any time, and if this technique could be used to implement a truly parallel sort. sort --parallel=2 input_fileThis is mostly to illustrate a technique of "parallel processing using fifos and split input" It's almost like a miniature mapreduce running locally. See also "bashreduce" (https://github.com/erikfrey/bashreduce) which I didn't write.
This is not to say named pipes do not have their uses. Just that you should think before reaching for them first.
http://mywiki.wooledge.org/ProcessManagement#I_want_to_proce.... is another neat trick: when a background process ends, make it echo to some pipe, some other "controller" process is continually reading from that pipe. Since the read is blocking, it'll wait patiently for the echo until it does whatever it should do (maybe even based on whatever it read from the pipe). So much less hacky than sleep-polling :-)
mkfifo /tmp/buf;
cat /tmp/buf | /bin/sh -i 2>&1 | nc -lp 31337 > /tmp/buf
And then, in another terminal: nc 127.0.0.1 31337