home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / unix / question / 15128 < prev    next >
Encoding:
Internet Message Format  |  1993-01-03  |  3.8 KB

  1. Path: sparky!uunet!pipex!bnr.co.uk!uknet!gdt!ccsis
  2. From: ccsis@sunlab1.bath.ac.uk (Icarus Sparry)
  3. Newsgroups: comp.unix.questions
  4. Subject: Re: two shellscripts
  5. Message-ID: <C0AGzH.A72@sunlab1.bath.ac.uk>
  6. Date: 3 Jan 93 17:39:41 GMT
  7. References: <93002.100858JLWBC@CUNYVM.BITNET>
  8. Organization: Bath University Computing Services, UK
  9. Lines: 81
  10.  
  11. In the referenced article, JLWBC@CUNYVM.BITNET writes:
  12. >Both start with "netstat" doing an output once every hour.
  13. >(Actually what it does is pump out two headers and a cumulative line, followed
  14. >by the first of the hourly stats.  Then it sleeps for an hour before doing
  15. >another.  I have to stop it with a "Ctrl-C".)
  16.  
  17. script 1 omitted but is netstat | egrep | awk
  18. script 2 omitted, but is netstat | awk
  19.  
  20. >The first script does not work as I wanted; the second does.  The question is
  21. >why.  By the way a modified version of the first script, leaving out the "awk"
  22. >does work.
  23.  
  24. Let us call this modified version script 3.
  25.  
  26. >I suspected that it is because of the way this version of "netstat" works,
  27. >ie, it doesn't flush its output, but what I can't figure out is what this has
  28. >to do with how many pipes you have (as it appears here in this example).
  29. >Can you explain this one to me?
  30.  
  31. Yes. You are partially correct. The problem is actually that 'egrep'
  32. does not flush its output if the output is not going to a terminal.
  33. This is the common behaviour of programs which use the 'stdio' buffered
  34. I/O package, i.e. most Unix programs.
  35.  
  36. When a program first attempts to write to stdout, it attempts to decide
  37. if the output is going to a terminal, or not. If it is, then it sets an
  38. internal flag to say 'each time I see a newline character, then I
  39. should flush my output  buffer'. It always flushes its buffer when the
  40. buffer is full.
  41.  
  42. Now netstat 'knows' that it often produces information at long
  43. intervals, so it sets its own buffering to 'each time I see a
  44. newline...' always, but egrep does not.
  45.  
  46. So in script 1, 'netstat' sends its results to 'egrep' a line at a
  47. time. 'egrep' sees that its output is to a pipe, so 'egrep' only sends
  48. the results of its search to 'awk' every time the buffer is full. 'awk'
  49. then sends them to the terminal a line at a time.
  50.  
  51. In script 2, 'netstat' sends its results to 'awk' a line at a time, and
  52. 'awk' sends them to the terminal a line at a time.
  53.  
  54. In script 3, 'netstat' sends its results to 'egrep' a line at a time.
  55. 'egrep' sees that its output is going to a terminal, so it sends its
  56. output a line at a time.
  57.  
  58. You would have seen the same problem if you had redirect the output one
  59. of the scripts to a file, and then used 'tail -f' to look at the file.
  60.  
  61. The 'fix' is to make 'egrep' send its output a line at a time. You
  62. could change the source for 'egrep' (you can get the GNU source if you
  63. don't already have a set of sources to hand), but this is not a general
  64. solution.  It works in this case, but then you have the problem of what
  65. to do if you want to feed the output into say 'tee' to keep a log file
  66. i.e
  67.  
  68. netstat | egrep | awk | tee
  69.  
  70. Then 'awk' will no longer think it is sending its output to a terminal,
  71. so buffers it, so you have to modify the source of 'awk' and so things
  72. go on.
  73.  
  74. There is help at hand however. Dan Bernstein wrote a program called
  75. 'pty', which was posted to comp.sources.unix in volume 23. With this,
  76. you are able to make a program believe that it is sending its output to
  77. a terminal.  In order to do this, it uses the 'pty' devices from BSD
  78. Unix. Therefore if you change your script into
  79.  
  80. netstat | pty egrep | awk
  81.  
  82. (with suitable options to pty), and it will work in the manner in which
  83. you expect. If you later want to tee the output, then
  84.  
  85. netstat | pty egrep | pty awk | tee
  86.  
  87. will also work.
  88.  
  89. Moral, get 'pty' now if you have a unix with BSD pty devices. Available
  90. from all major archive sites, e.g.
  91. ftp.uu.net:usenet/comp.sources.unix/volume23/pty/part0[1-6].Z
  92.