0

I have a named fifo and I am writing random number to this fifo. When I write to fifo I want to find written text in numbers.txt file and write the result row to stdout.

Content of numbers.txt file is:

1 one
2 two
3 three
... and so on

I want to search text which piped to grep in this file. For example If I write 1 to named pipe, grep should print 1 one to stdout.

I am running command shown as below in first terminal:

cat <> myfifo | grep -f - numbers.txt

And I am writing to fifo in another terminal show as below:

echo 1 > myfifo

But I can't see any output in stdout in first terminal window.

I want to see 2 two in first terminal output when I execute echo 2 > myfifo in second terminal window. How to achive this?

  • use the command tail -f [your filename along with path here without brackets] this could be helpful to you... this immediately reflects the changes to the screen as soon as the contents of file changes... – sanjeev Dec 3 '16 at 19:29
  • grep -f myfifo numbers.txt, as in my answer. – Tomasz Dec 3 '16 at 20:20
  • @tomas I tried this but not worked. I am writing text to pipe but grep -f myfifo numbers.txt command not printing any output to stdout. – Mesut Tasci Dec 3 '16 at 20:33
2

cat <> myfifo opens the named pipe for both reading and writing. As long as the pipe is open for writing, the reader doesn't reach the end of the file. So cat never reaches the end of its input, so it never closes its output which is the pipe to grep, so grep never reaches the end of the input for the -f option.

Grep can't start searching until it knows what pattern to search. So it remains blocked forever without even starting to read from numbers.txt.

If you want to search for the patterns coming through myfifo then just use

grep -f myfifo numbers.txt

You can also write it cat <myfifo | grep -f - numbers.txt but that's needlessly complicated.

Note that a pattern like 1 matches any line containing 1, such as 11 eleven. If you want to match only lines that begin with one of the numbers coming through the pipe, use something like

<myfifo sed 's/^0*/^0*/; s/$/ /' | grep -f - numbers.txt
  • This worked fine. But fifo is closing after write to it. Is this expected behavior? I solved this with grepping fifo in a infinite while loop. But this is not working if I write to pipe with continious stream. For example: I have a shell script printnumbers.sh that looping infinite and printing 1,2,3,... to stdout each second. I am running ./printnumbers.sh > myfifo in one terminal, and in another terminal: while true; do grep -f myfifo numbers.txt | awk '{print $2; system("")}' done This printing to stdout when I stop print to fifo. – Mesut Tasci Dec 4 '16 at 18:12
  • @mesuutt When the last writer on a pipe closes the pipe, readers get an end-of-file indication. I don't understand the rest of your comment. What are you trying to achieve? As I explain in my answer, grep reads the patterns before it starts processing the text to search. Do you want to search the data again each time a new pattern comes on the pipe? If so you will need to call grep (or awk) in a loop, since it has to read the data again and again each time. – Gilles 'SO- stop being evil' Dec 4 '16 at 18:34
  • Yes I want to search the data again each time a new pattern comes to pipe. Also I read from pipe within a loop. I have a bash script file printnumbers.sh that print numbers each second in infinite loop. Your solution works if I write to pipe as echo 1 > myfifo and print one to stdout but if I write to pipe numbers as: ./printnumbers.sh > myfifo not printing anything to stdout due to stop the ./printnumbers.sh > myfifo. gist.github.com/mesuutt/92e1d6286c442b2003fe2c67d2133d7b – Mesut Tasci Dec 4 '16 at 19:03
0

I don't know why your code doesn't work, I guess it has to do with the <> redirection with the receiving cat and it not responding to the End-Of-Text sign, so that nothing get through to grep. Again, I guess. Someone more knowledgeable might explain this.

Anyhow, the following will do.

Writing terminal:

$ printf "%s\n" {1..7} > myfifo

Or:

$ cat > myfifo
1
2
3
4

Receiving terminal:

$ grep -f myfifo numbers.txt 
1 one
2 two
3 three
4 four
5 five
6 six
7 seven

Or this:

cat myfifo | grep -f - numbers.txt
  • I tried this but not worked. I am writing text to pipe but command not printing any output to stdout. Also I want to get 1 one as output when I write 1 to named pipe not all of the content of numbers.txt – Mesut Tasci Dec 3 '16 at 20:36
  • @mesuutt It should be fine. Make sure you're indeed writing the the same pipe as you read from, so namely that both terminals are in the same directory. Use pwd if needed. – Tomasz Dec 3 '16 at 20:54
  • cat myfifo works as expected but cat myfifo | grep -f - numbers.txt or grep -f myfifo numbers.txt not printing anything to stdout. I have grep 2.25 version. – Mesut Tasci Dec 3 '16 at 21:46
  • @mesuutt Same as me. Which version of Bash do you have? – Tomasz Dec 3 '16 at 21:58
  • I tested on bash 4.3.46 and zsh 5.2 on Arch linux. – Mesut Tasci Dec 3 '16 at 22:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.