LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-25-2011, 10:52 AM   #1
grob115
Member
 
Registered: Oct 2005
Posts: 542

Rep: Reputation: 32
grep chain breaks due to pipe buffer


Hi, it appears if I pipe two grep together, I don't see the output on stdout. For example

This works
tail -f file.log | grep 'content 1'

This doesn't work
tail -f file.log | grep 'content 1' | grep 'content 2'

Believe the issue is due to buffering by the pipe between the two greps. Now the questions:
1) Why wouldn't the same buffering issue appear between the tail and the first grep?
2) How can I control how much buffering is applied?
 
Old 10-25-2011, 11:01 AM   #2
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541

Rep: Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065
You're most likely overflowing the system buffer; you might want to try xargs to avoid that.

Hope this helps some.
 
Old 10-25-2011, 11:09 AM   #3
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,779

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
The 'tail' program with the "-f" option always line-buffers its output, unlike the usual default of line-buffering only when stdout is connected to a terminal and block-buffering otherwise.

For 'grep', you can use the "--line-buffered" option to make it buffer in the same manner as "tail -f".
 
Old 10-25-2011, 11:09 AM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Quote:
Originally Posted by grob115 View Post
This doesn't work
tail -f file.log | grep 'content 1' | grep 'content 2'
Or perhaps there are no lines having both 'content 1' and 'content 2'? (Or bring more concrete example.)
 
Old 10-25-2011, 11:38 AM   #5
grob115
Member
 
Registered: Oct 2005
Posts: 542

Original Poster
Rep: Reputation: 32
Quote:
Originally Posted by rknichols View Post
The 'tail' program with the "-f" option always line-buffers its output, unlike the usual default of line-buffering only when stdout is connected to a terminal and block-buffering otherwise.

For 'grep', you can use the "--line-buffered" option to make it buffer in the same manner as "tail -f".
You mean the following?
tail -f file.log | grep --line-buffered 'content 1' | grep 'content 2'
 
Old 10-25-2011, 04:20 PM   #6
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,779

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
Quote:
Originally Posted by grob115 View Post
You mean the following?
tail -f file.log | grep --line-buffered 'content 1' | grep 'content 2'
Yes. Didn't it work? Works fine for me. Any line that matches both grep expressions shows up immediately on the terminal.
 
1 members found this post helpful.
Old 10-26-2011, 10:00 AM   #7
grob115
Member
 
Registered: Oct 2005
Posts: 542

Original Poster
Rep: Reputation: 32
Hi, yes it did work. Not only does grep have buffer, the same is also true for awk and sed. Have you run across the unbuffer command? I don't have it on my OS but have seen elsewhere online people are talking about it. Wonder how it compares with the commands own built in switches for turning off buffering.

One thing though, it appears the unbuffer switch for sed (ie sed -u doesn't turn the buffer off completely). I notice that the following:
tail -f logfile.log | egrep --line-unbuffered <filter> | awk '{print{$1} fflush()}' | sed -u -e 's/something//g'

Is sometimes one line behind the following.
tail -f logfile.log | egrep --line-unbuffered <filter>

I'm blaming it on sed because the man page says:
Quote:
-u, --unbuffered

load minimal amounts of data from the input files and flush the output buffers more often
Note it says more often, and not immediately, or perform line buffering.

Also find the following very helpful.
http://www.pixelbeat.org/programming/stdio_buffering/

Last edited by grob115; 10-26-2011 at 10:02 AM.
 
Old 10-26-2011, 11:12 AM   #8
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,779

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
Quote:
Originally Posted by grob115 View Post
Hi, yes it did work. Not only does grep have buffer, the same is also true for awk and sed. Have you run across the unbuffer command?
Anything that uses stdio is likely to do similar buffering. The default for stdio is to use line buffering for output to file descriptors connected to a terminal, and block buffering (typically 4K blocks) otherwise, except for stderr, which is always line-buffered. It's easy enough for the program to override the default, but it takes specific action to do so.

Yes, I've seen the 'unbuffer' command. It's part of the 'expect' package, and works by connecting a program's output descriptor to a pseudo-terminal device and then passing the data along to the next stage of the pipeline. When I last tried it several years ago, it didn't work -- output was still block-buffered. I haven't had occasion to try it since.

The issue with 'sed' is that it has an additional layer of internal buffering independent of stdio. You can spend an hour or so reading the manpage about it, but when a look at that manpage I am always reminded of an old comment deep in the source for the kernel's scheduler, "You aren't expected to understand this."

Last edited by rknichols; 10-26-2011 at 11:21 AM. Reason: Add paragraph about 'sed'
 
Old 10-28-2011, 10:17 PM   #9
grob115
Member
 
Registered: Oct 2005
Posts: 542

Original Poster
Rep: Reputation: 32
Thanks. Is there a way to switch to line buffering for the PIDs triggered under my current login or a specific PPID? Or to change the buffering size from 4k to 0?
 
Old 10-28-2011, 11:28 PM   #10
rknichols
Senior Member
 
Registered: Aug 2009
Distribution: Rocky Linux
Posts: 4,779

Rep: Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212Reputation: 2212
Quote:
Originally Posted by grob115 View Post
Thanks. Is there a way to switch to line buffering for the PIDs triggered under my current login or a specific PPID? Or to change the buffering size from 4k to 0?
Basically, no. You would have to modify and re-compile each program for which you wanted that change, or else make equivalent changes to the stdio library.

FWIW, some limited testing I just tried with the 'unbuffer' command shows that it seems to be working properly these days. I don't recall just what the issue was with it in the past, though I do know I wasn't the only person having the problem.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Linux Pipe Buffer size traku Linux - Newbie 1 10-23-2009 07:48 AM
Trying to understand pipes - Can't pipe output from tail -f to grep then grep again lostjohnny Linux - Newbie 15 03-12-2009 10:31 PM
LXer: Getting Error Values From The Middle Of A Pipe Chain In Bash LXer Syndicated Linux News 0 12-20-2007 11:20 AM
Controlling pipe buffer size in C shunker Programming 4 01-10-2004 06:52 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:30 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration