Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add `watch' command to a shell script?

I have a script that greps and awks and counts for ip addresses with multiple http status codes. It doesn't really matter what the script is though, because my goal is as follows:

I want to invoke the `watch' command inside this script so that it will update the display every few seconds with new data received from the dynamic apache logs.

i can call my script fine as follows:

$ watch --no-title ./bad_request.sh

But I would much rather have the `watch' command inside the script itself, to make calling the script from the command prompt much cleaner.

Here is the script:

#!/bin/bash
#identify repeated offenders through 401 and 403 status codes
  for ip in `awk '{print $1}' /var/log/apache2/* | sort -u`; do echo -n "$ip "; awk '{print $1 " " $9}' /var/log/apache2/* | egrep "( 401| 403)"| grep -c $ip; done | sort -k2 -r

Now, I have tried just inserting "watch -d --no-title" inside the script, right before the for loop, but it errors out angrily. I think it's because it is only processing until it reaches the end of the first command. I've tried putting backticks, and $() around the entire script, as well. I've also tried making the bulk of the script a bash function, and calling watch on the function. No dice.

Any ideas?

By the way, I'm also open to improvements on the script - I do realize it's a bit redundant/inefficient. Of course, that should probably be reserved for a different Stack Overflow question.

Thanks,

Kevin

EDIT: And one more thing, I can just call while true; do <bulk of script>; sleep 1; clear; but I hate that. It works, but the screen flickers, and it's just not the right way to do this.

EDIT 2: Another nasty hack that works, is to simply create two scripts. The first one is:

watch --no-title ./bad_request

And then just call that script. That works fine, but there has to be a better way.

EDIT 3 (sorry...): I took the -d flag off of `watch'. It's not necessary for my script.

like image 977
Kevin Avatar asked Mar 15 '26 17:03

Kevin


2 Answers

Heed the unix philosophy:

 A program should do one and only one thing and do it well.

Applied to your case:

A script should do one and only one thing and do it well.

Your "nasty hack" is actually a step in the right direction.

You'll never know if one day you'll need to "watch --no-title" on another script. At that point if you follow the unix philosophy you'd already have a script to do that.

You already see one complication of trying to make a script do too many things at once - quote hell.

Keep it simple.

like image 53
holygeek Avatar answered Mar 17 '26 20:03

holygeek


the correct usage would be:

watch -d --no-title "/bin/bash for ip in `awk '{print $1}' /var/log/apache2/* | sort -u`; do echo -n "$ip "; awk '{print $1 " " $9}' /var/log/apache2/* | egrep '( 401| 403)'| grep -c $ip; done | sort -k2 -r"
like image 24
Thomas Berger Avatar answered Mar 17 '26 18:03

Thomas Berger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!