开发者

How can I match a pattern over TCP?

I'm trying to write a monitoring script. It should connect to some port on my server, read the output, and if the output is the expected value, print 1 otherwise 0.

I'm working on a solution involving cat < 开发者_C百科/dev/tcp/hostname/port, but the solution eludes me. Maybe something involving expect? I'd prefer a bash script solution. Help appreciated!


All other solutions use netcat for network support, but you can do away with it if your bash is recent enough and compiled with --enable-net-redirections (which is, as far as I can tell, all but Debian and Ubuntu; feel free to comment if I should adjust).

Then grep can do the actual testing. Its return code is a shell one (0 for success, nonzero for failure), so you'd need to invert that, but bash handles it just fine.

In a nutshell:

< /dev/tcp/host/port grep -q 'expected value'
echo $(( 1 - $? ))


you can use netcat:

echo "GET /"|netcat google.com 80

and then pipe the output to your processing script


#!/bin/bash
EXPECTED="hello"
SERVER="example.com"
PORT="123"

netcat $SERVER $PORT | grep -F -q "$EXPECTED"

if [ $? ]; then
  echo 1
else
  echo 0
fi


there are little examples here. you can take reference to it. However, you should note that it also depends on what services runs on your port and what protocol it speaks.

if you are connecting to web server, common port is 80. But if you running your own application running as a server, make sure your script knows how to "talk" to each other.

another resource you can look at here. Its gawk though, so if you have gawk, then you may want to try it. (you can "port" to bash too)


I would suggest you use a popen approach. That way you can read with whatever command you like (i.e. nc) and handle the output iteratively. This can all be spawned by a bash script if necessary.

For example:

#!/usr/bin/env ruby

IO.popen("nc host 4560") do |stdout|
   while line = stdout.gets
      if line =~ /pattern/
         puts "1"
      else
         puts "0"
      end
   end
end

Obviously you would need to substitute pattern with whatever you were looking for. This has the advantage of comparing each line instead of the entire output of the command. I'm not sure which is preferable in your case. I assume from you mentioning expect that you want a line-by-line approach.


Here is the script in Bash shell which involves HTTP request:

exec {stream}<>/dev/tcp/example.com/80
printf "GET / HTTP/1.1\nHost: example.com\nConnection: close\n\n" >&${stream}
grep Example <&${stream}
[ $? -eq 0 ] && echo Pattern match || echo Pattern not match

See also: More on Using Bash's Built-in /dev/tcp File (TCP/IP).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜