netstat grep regex suspend script help

Hi

I am trying to create a suspend script which will suspend the system only if it cant find port 9982 four or more times OR 192.168.0.:microsoft-ds ESTABLISHED in the output of netstat -t.

I am struggling with the 9982 bit, googling etc I came up with

if netstat -t|grep -P "(9982){4,}"

but this does not return anything when there is four or more instances of 9982.

Also is this script okay?

#!/bin/bash
if netstat -t|grep -P "(9982){4,}" ; then
	exit
	elif
	netstat -t|grep -P "192.168.0.:microsoft-ds ESTABLISHED" ; then
	exit
        elif
	echo pm-suspend
fi 

Any help would be appreciated :slight_smile:

I have a question.

When you say 9982 four or more times, do you mean 4 lines with port number: 9982 or 4 or more alphanumeric character after port number: 9982?

Can you post a sample output of netstat which you are trying to capture for port number: 9982?

I mean four or more instances of port 9982 in the whole of the output so it would match the below and more instances of port 9982 appearing in the output:

Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 htpc.local:9982         192.168.0.4:62101       ESTABLISHED
tcp        0      0 htpc.local:50767        htpc.local:9982         ESTABLISHED
tcp        0      0 htpc.local:40573        192.168.0.2:mysql       TIME_WAIT
tcp        0    420 htpc.local:9982         192.168.0.4:62124       ESTABLISHED
tcp        0      0 htpc.local:9982         htpc.local:50767        ESTABLISHED
tcp        0      0 htpc.local:40574        192.168.0.2:mysql       TIME_WAIT
tcp        0      0 htpc.local:40572        192.168.0.2:mysql       TIME_WAIT
tcp        0     52 htpc.local:ssh          192.168.0.4:60655       ESTABLISHED

Try this code:-

#!/bin/bash

if [ `netstat -t | grep ":9982" | wc -l` -ge 4 ]
then
      exit 1
elif [ `netstat -t | grep "192.168.0.:microsoft-ds ESTABLISHED" | wc -l` -ne 0 ]
then
      exit 1
else
      echo pm-suspend
fi

I hope it helps.

Thanks I'll try it.

Can you explain wc -l` -ge ?

wc -l counts the number of lines
-ge Greater than or Equal to check

1 Like

Yes I think this will work after testing with echo, I now just need to google how to cron it.

Thank you!

Note: grep has a flag for counting:

grep ":9982" | wc -l

could be replaced by:

grep -c ":9982"

--
To prevent false positives, better use a delimiter at the end as well, a space in this case:

grep -c ":9982 "
1 Like

This script is working great but there is another issue I need to add to it. I dont want the machine to suspend if there is an active recording and unfortunately the port rule doesn't catch this however the below script is supposed to take account of recordings. Is it possible to incorporate the relevant section into mine?

web address lonelycoder.com/redmine/boards/4/topics/906

I can't post urls yet.

That URL is obsolete. Please post valid one.

strange, here is what is on the page:

#!/bin/bash
#
#
# modyfy if different location for tvheadend dvr/log path
cd ~hts/.hts/tvheadend/dvr/log

######################

start_date=0
stop_date=0
recording=0
pingcount=0

# wait for at least 60 seconds to let the calling recording expire
sleep 60

current_date=`date +%s`

for i in $( ls ); do
tmp_start=`cat $i | grep '"start":' | cut -f 2 -d " " | cut -f 1 -d ","`
tmp_stop=`cat $i | grep '"stop":' | cut -f 2 -d " " | cut -f 1 -d ","`

# check for any current recording
if [ $((tmp_stop)) -gt $((current_date)) -a $((tmp_start)) -lt $((current_date)) ]; then
 recording=1
fi
done

#if [ $((recording)) -ne 0 ]; then
# echo "Recording in progress" 
#fi

# check to see if there's an active client
pingcount=$(ping -c1 192.168.1.41 | grep 'received' | awk -F ',' '{print $2}' | awk '{ print $1}')
#echo "Pingcount is $pingcount" 

# do the final check, no pingcount and no recording means we can suspend
# 
if [ $((pingcount)) -eq 0 -a $((recording)) -eq 0 ]; then
 #echo "XBMC is NOT active and NO recording in progress, so going into SUSPEND" 
 sudo /usr/sbin/pm-suspend
fi

---------- Post updated at 07:29 AM ---------- Previous update was at 06:17 AM ----------

this should work if i get my if s in the right place

#!/bin/bash
sleep 30
if [ `netstat -t | grep -c ":9982"` -ge 3 ]
then
      exit 1
elif [ `netstat -t | grep -c "192.168.0.:microsoft-ds ESTABLISHED"` -ne 0 ]
then
      exit 1
elif
cd ~billy/.hts/tvheadend/dvr/log
current_date=`date +%s`

for i in $( ls ); do
tmp_start=`cat $i | grep '"start":' | cut -f 2 -d " " | cut -f 1 -d ","`
tmp_stop=`cat $i | grep '"stop":' | cut -f 2 -d " " | cut -f 1 -d ","`

# check for any current recording
if [ $((tmp_stop)) -gt $((current_date)) -a $((tmp_start)) -lt $((current_date)) ]; then
 echo recording in progress
fi
done
else
      echo pm-suspend
fi

Ok, you got the script & this can be added to your script. Now what kind of assistance you need?

FWIW lonelycoder.com does not work, www.lonelycoder.com does. But it is good practice to post the code here anyway...

I have slot in the bit of the code from the lonely coder page that I need as below but not sure what to do with the extra if and where to put it?

---------- Post updated at 01:12 PM ---------- Previous update was at 11:34 AM ----------

#!/bin/bash
sleep 30
if [ `netstat -t | grep -c ":9982"` -ge 3 ]
then
      exit 1
elif [ `netstat -t | grep -c "192.168.0.:microsoft-ds ESTABLISHED"` -ne 0 ]
then
      exit 1
elif
cd ~billy/.hts/tvheadend/dvr/log
current_date=`date +%s`

for i in $( ls ); do
tmp_start=`cat $i | grep '"start":' | cut -f 2 -d " " | cut -f 1 -d ","`
tmp_stop=`cat $i | grep '"stop":' | cut -f 2 -d " " | cut -f 1 -d ","`

# check for any current recording
if [ $((tmp_stop)) -gt $((current_date)) -a $((tmp_start)) -lt $((current_date)) ]; then
 echo recording in progress
fi
done
else
      echo pm-suspend
fi

---------- Post updated 03-11-12 at 09:14 AM ---------- Previous update was 02-11-12 at 01:12 PM ----------

I have tried:

#!/bin/bash
sleep 30


current_date=`date +%s`

for i in $( ls ); do
tmp_start=`cat $i | grep '"start":' | cut -f 2 -d " " | cut -f 1 -d ","`
tmp_stop=`cat $i | grep '"stop":' | cut -f 2 -d " " | cut -f 1 -d ","`

# check for any current recording
if [ $((tmp_stop)) -gt $((current_date)) -a $((tmp_start)) -lt $((current_date)) ]; then
 echo recording in progress
fi
done
if [ `netstat -t | grep -c ":9982"` -ge 3 ]
then
      echo live tv
elif [ `netstat -t | grep -c "192.168.0.:microsoft-ds ESTABLISHED"` -ne 0 ]
then
      echo media playing
else
      echo pm-suspend
fi

but get error

/home/billy/bin/grep.sh: line 12: $i: syntax error: operand expected (error toke                    n is "$i")

Correction:-

for i in $( ls ); do
if [ -f "$i" ]; then # Work only on files not directories.
tmp_start=`cat $i | grep '"start":' | grep -v script_name | cut -f 2 -d " " | cut -f 1 -d ","`
tmp_stop=`cat $i | grep '"stop":' | grep -v script_name | cut -f 2 -d " " | cut -f 1 -d ","`

# check for any current recording
if [ $((tmp_stop)) -gt $((current_date)) -a $((tmp_start)) -lt $((current_date)) ]; then
 echo recording in progress
fi
fi
done

Where script_name is the file name of same script. So replace it with the file name of your script.

I hope it helps.

Thank you, this is working now I had missed out the dvr log!!

#!/bin/bash
cd ~billy/.hts/tvheadend/dvr/log
current_date=`date +%s`

for i in $( ls ); do
tmp_start=`cat $i | grep '"start":' | cut -f 2 -d " " | cut -f 1 -d ","`
tmp_stop=`cat $i | grep '"stop":' | cut -f 2 -d " " | cut -f 1 -d ","`

# check for any current recording
if [ $((tmp_stop)) -gt $((current_date)) -a $((tmp_start)) -lt $((current_date)) ]; then
 exit 1
fi
done
if [ `netstat -t | grep -c ":9982"` -ge 4 ]
then
      exit 1
elif [ `netstat -t | grep -c "192.168.0.:microsoft-ds ESTABLISHED"` -ne 0 ]; then
      exit 1
else
      sudo pm-suspend
fi