Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm working on a set of scripts to monitor some external services that log to a TCP port.

function handleMessage {
  while read message
  do
    # Handle $message
  done
}
nc -d $ipadd $port | handleMessage

This code works fine when log messages are delimited by new lines like the following

Service started

ERROR: Something terrible happened

Service stopped

But one of the services delimits messages using LOGXXXX and allows new lines within messages so it's output looks more like this:

LOG0001 Service startedLOG0002 ERROR: Something terrible happened

NullPointerException at SomeMethod (File1.java)

SomeOtherMethod (File2.java)LOG0003 Service stopped

Using my code above handleMessage is called for each of the lines instead of for each set of LOGXXXX segments and if time passes with no messages containing newlines my script gets very far behind in handling messages.

Is there an option on nc or another program I can use to read from this TCP port and break on a custom delimiter, or some option to have a bash function handle each write to stdout instead of only being called for each line?

share|improve this question
3  
I think your best bet is to pipe nc's output to sed to do the line-splitting, and give the result of that mangling to your script. –  vonbrand Feb 1 '13 at 19:48
    
You could try poking around with bash's variable IFS, i.e. set IFS=LOG in both the command line and the function. But I agree that sed might be worth to study. –  rank Oct 23 '13 at 12:21

1 Answer 1

up vote 1 down vote accepted

The problem here is in your while read message line. read by default terminates on a newline, but you can pass it another character with the -d option.

The question to ask is in your LOGXXXX lines, how does the script know when the entry is finished? If you can put a special character at the end then you can use read -d. Otherwise, you could replace the newlines with something else and then put them back after.

So in your example:

function handleMessage {
  while read message
  realmessage=`echo $message | tr '|' '\n'`
  do
    # Handle $realmessage
  done
}
nc -d $ipadd $port | tr '\n' '|' | handleMessage

So you're replacing all the newlines with a | so that it'll all get in the read call, and then you split it out after.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.