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?

3
  • 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... Dec 3, 2016 at 19:29
  • grep -f myfifo numbers.txt, as in my answer.
    – user147505
    Dec 3, 2016 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. Dec 3, 2016 at 20:33

2 Answers 2

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
3
  • 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. Dec 4, 2016 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. Dec 4, 2016 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 Dec 4, 2016 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
6
  • 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 Dec 3, 2016 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.
    – user147505
    Dec 3, 2016 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. Dec 3, 2016 at 21:46
  • @mesuutt Same as me. Which version of Bash do you have?
    – user147505
    Dec 3, 2016 at 21:58
  • I tested on bash 4.3.46 and zsh 5.2 on Arch linux. Dec 3, 2016 at 22:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .