Tee does not write to screen or file
I use the following command to find out which virtual hosts are receiving traffic on my server (alternatives are welcome).
ngrep 'Host:' port 80 -t -W byline -q | grep '^Host'
I want to be able to analyze the number of hits over a period of time, and also see what is happening. For this, I tried to write the output to a file showing it with tee.
ngrep 'Host:' port 80 -t -W byline -q | grep '^Host' | tee ~/hosts.log
However, nothing is printed to the screen or written to the file.
I've tried different file locations, outside of my session screen
- no difference. Does it require grep
special handling?
source to share
In playback mode, ngrep
and grep
is line buffering. Here's how you can get around the problem you are seeing:
% sudo ngrep 'Host:' port 80 -t -W byline -d lo -q -l |grep --line-buffered '^Host:' |tee foo.log
Note that it ngrep
uses -l
stdout to create buffering, and grep
uses it --line-buffered
for that.
(I added -d lo
for my own testing only.)
source to share
You can use a command stdbuf
like:
ngrep 'Host:' port 80 -t -W byline -q | stdbuf -o0 grep '^Host' | tee /tmp/hosts
I am setting the buffer stdout
grep
to zero.
stdbuf
is a common hammer that works for related programs glibc
as the output / input buffering happens in libc. The output of the program that writes to the terminal will receive line buffering, the output of the program that is output to a pipe or file will be block buffered - unless the program itself is named flush()
. You can use stdbuf
to change this behavior.
Btw, ngrep
and tee
seem to be calling flush()
( ngrep
on stdout, tee
on stdin) since we didn't need to use stdbuf
for them.
I would accept MicahElliot's answer as it is --line-buffered
more specific for grep
and should be used here. stdbuf
- a good alternative for programs that don't offer this option (and for guys like me who haven't read the grep man page before);
source to share