218

I'd like to run this command:

watch -n 1 tail -n 200 log/site_dev.log | grep Doctrine

But it does not run, because "I think" that the grep tries to run on the watch instead of the tail...

Is there a way to do something like

watch -n 1 (tail -n 200 log/site_dev.log | grep Doctrine)

Thanks a lot!

4 Answers 4

324

Surround the command with quotes

watch -n 1 'tail -n 200 log/site_dev.log | fgrep Doctrine'
2
  • 4
    What if the pipeline also contains quotes (such as awk '{print $3}')? Edit: Like this
    – OrangeDog
    Jun 6, 2018 at 16:28
  • 4
    you can escape those chars with \ , ie watch -n 'awk \'{print $3}\''
    – lev
    Sep 21, 2018 at 10:44
33

I might be wrong, but wouldn't this achieve the same thing (viewing matching log lines as they get added) more simply?

tail -f -n 200 log/site_dev.log | grep Doctrine
4
  • 8
    I agree this may be more efficient as far as CPU is concerned, but in the context of the topic "Using watch with pipes" it doesn't use watch so isn't an answer. This might be a case of a poor example question as watch and pipes seem to appear frequently not in the context of tail. Jan 20, 2014 at 0:07
  • 1
    No, I think you're confusing the means and the end. The user clearly wanted to see Doctrine arriving in a growing file, and when he looked in his toolbox, the only thing he found was watch. What he really needed to know was tail -f. See also meta.stackexchange.com/questions/66377/what-is-the-xy-problem
    – dland
    Mar 21, 2016 at 11:03
  • 11
    I think these are both acceptable answers. The top and accepted answer correctly answers the exact question posed, and this answer correctly identifies the XY problem that OP created for themselves and provides the solution they really wanted in the first place. Both answers could easily be useful to someone coming across this question.
    – cdhowie
    Apr 14, 2016 at 16:14
  • 2
    I was looking for a way to watch shellcheck *.sh | grep line | wc -l and the accepted answer was useful for me. Jan 3, 2017 at 12:29
7

You can surround the command with quotes:

watch -n 1 'tail -n 200 log/site_dev.log | fgrep Doctrine'

If the command has quotes in it, you can use a different type of quotes with appropriate escaping:

watch -n 1 $'tail -n 200 log/site_dev.log | fgrep \'Doctrine.*\''

If you are trying to do something really clever, put the command or commands in a script and use that with watch:

cat <<EOF >/tmp/watch-command
tail -n 200 $(pwd)/log/site_dev.log | fgrep Doctrine
EOF
chmod +x /tmp/watch-command
watch /tmp/watch-command

Make sure to account for relative paths if necessary.

1
0

Use double quotes, as watch is executing the command:

watch "ls -la | wc -l"

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.