fswatch with grep not piping

I want to use fswatch to run a file through my unit test framework whenever I save.

As a test, I run fswatch and make a minor change to /my/path/test.txt in my text editor and get the output I expected:

$ fswatch . | xargs -I {} echo {} {}
/my/path/test.txt /my/path/test.txt

But if I insert a grep in the middle and repeat the process I get no output:

$ fswatch . | grep test | xargs -I {} echo {} {}

What am I doing wrong?

Edit:

fswatch + grep works fine by itself

$ fswatch . | grep test
/my/path/test.txt

Answers

As already said, --line-buffered tells grep not to block-buffer output, hence writing entire lines immediately to standard output. Block-buffering is the default behaviour when grep is writing to a pipe, line-buffering is the default when it's writing to a terminal.

Now: as explained in fswatch documentation, file names can contain new line characters. Hence the existence of -0 (as other file-handling utilities such as find have). If you tell grep to line-buffer and you hit such a file you will end up with a corrupt fswatch record.

Why aren't you filtering using filters instead? For simple filtering they're easy to use. That way fswatch will internally match file names without your having to worry about these peculiarities and corner-cases.

Posted on by Enrico M. Crisostomo

man grep:

   --line-buffered
          Use line buffering on output.   This  can  cause  a  performance
          penalty.

When using grep as last pipe command then linebuffered is the deault.

Posted on by Ipor Sircer