crsuarezf
crsuarezf

Reputation: 1301

Linux watch command not working in script

Hello Everybody there.

I'm doing an script for monitoring periodically the connection to a port (in this case 80).

I write this short script.

echo '=================================';a=`sudo lsof -i :80`;echo $a | awk '{print $1," ",$2," ",$3," ",$8}'; b=`echo $a | wc -l`; b=$(($b - 1));echo Total SSH Connections: $b;echo '================================='

The output is:

=================================  
COMMAND   PID   USER   NODE  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
acwebseca   90   root   TCP  
Total SSH Connections: 19  
=================================  

But when a try to use watch command it throws me errors and I cannot see the output when I cancel the command i see an error like this:

sh: PID: command not found
                          sh: -c: line 1: syntax error near unexpected token `('
                                                                                sh: -c: line 1: `acwebseca  90 root   37u  IPv4 0x81ae738f91e7bed9      0t0  TCP 192.168.0.11:49915->108.160.163.33:http (ESTABLISHED)'

How can i fix this.

watch -n 2 "echo '=================================';a=`sudo lsof -i :80`;echo $a | awk '{print $1," ",$2," ",$3," ",$8}'; b=`echo $a | wc -l`; b=$(($b - 1));echo Total SSH Connections: $b;echo '================================='"

Upvotes: 2

Views: 6015

Answers (3)

CS Pei
CS Pei

Reputation: 11047

quote from man watch,

Note that command is given to "sh -c" which means that you may need
to use extra quoting to get the desired effect.  You can disable this
with the -x or --exec option, which passes the command to exec(2) instead.

Note that POSIX option processing is used (i.e., option processing stops
at the first non-option argument).  This means that
flags after command don't get interpreted by watch itself.

Upvotes: 2

William Pursell
William Pursell

Reputation: 212654

This is more of a comment than an answer, since I'm not going to address passing the command to watch. But formatting comments is hard. You can greatly simplify the command by doing more in awk:

 sudo lsof -i :80 | awk '
      BEGIN { d="================================="; print d}
      {print $1," ",$2," ",$3," ",$8}'
      END { print "Total SSH Connections:", NR-1; print d}'

Upvotes: 2

John Zwinck
John Zwinck

Reputation: 249642

It works if you write the script into a file and execute it. Then it doesn't have to be a hideous one-liner, but can look like this:

echo '================================='
a=`sudo lsof -i :80`
echo $a | awk '{print $1," ",$2," ",$3," ",$8}'
b=`echo $a | wc -l`
b=$(($b - 1))
echo Total SSH Connections: $b
echo '================================='

Just put it in a file, and run watch my-script.sh. This solves the problem, and makes the code readable at the same time.

Edit: if you really want a one-liner, which is a bad idea, you can try this:

watch 'echo =================================;a=`lsof -i :80`;echo $a | awk "{print \$1, \$2, \$3, \$8}"; b=`echo $a | wc -l`; b=$(($b - 1));echo Total SSH Connections: $b;echo ================================='

Basically I adjusted the quoting to make it run properly; I may have messed up the awk formatting slightly, but I'm sure you can hack it back into shape if needed.

Upvotes: 5

Related Questions