LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (http://www.linuxquestions.org/questions/linux-general-1/)
-   -   Simple bash script help (http://www.linuxquestions.org/questions/linux-general-1/simple-bash-script-help-509790/)

zok 12-12-2006 03:31 PM

Simple bash script help
 
I wrote up a simply script to find out which users have and have not logged into our mail server over the past month. It works if I only analyze one log file ('checklist' is a list of usernames we want to check):

userlist=`cat checklist`
for user in $userlist; do
if grep "Login: $user " /var/log/dovecot.imap.info.log.1 > /dev/null; then
echo $user has logged on
else
echo $user has NOT logged on
fi
done


The problem is that we have a lot of log files to go through, and when I try to use a wildcard in the filename to search through all the logs (var/log/dovecot.*.info.log.*) it doesn't work. I don't know exactly what's happening, but it incorrectly reports that accounts have logged in that I know have not. Does anyone know how I can modify this script to search through multiple log files to find any instance of "Login: $user "?

Thanks,
Jason

ilikejam 12-12-2006 03:46 PM

Hi.

Remove the /dev/null redirection and add -n, so you can see where and in which file the grep is picking up false positives:

Code:

if grep -n "Login: $user " /var/log/dovecot.*.info.log.*; then
Dave

zok 12-14-2006 03:03 PM

Quote:

Originally Posted by ilikejam
Hi.

Remove the /dev/null redirection and add -n, so you can see where and in which file the grep is picking up false positives:

Code:

if grep -n "Login: $user " /var/log/dovecot.*.info.log.*; then
Dave

Thanks for the advice; unfortunately, this doesn't seem to help. There is no output from the grep statement for the false positives, but the script still says the user has logged on. It's as if for some reason the exit status of the grep command is positive -- at some point, somehow, when going through the various log files -- even though it doesn't actually find a match. For example:

$ sudo ./activeacct
root has logged on
daemon has logged on
adm has logged on
sync has logged on
shutdown has logged on
/var/log/dovecot.imap.info.log.21.gz:3897:imap-login: Nov 23 10:57:58 Info: Login: jjames [130.X.X.X]
jjames has logged on
skane1 has logged on

As you can see, grep does find something for jjames and correctly reports that he has logged on, but it doesn't find anything for daemon, adm, sync, etc, yet still reports that they have logged on. (By the way, I'm using zgrep instead of grep, since most of the logs are zipped).

dimsum 12-15-2006 11:02 AM

Quote:

Originally Posted by zok
It's as if for some reason the exit status of the grep command is positive -- at some point, somehow, when going through the various log files -- even though it doesn't actually find a match.

You're right. Look at this example (there is no 'poppy' in either of the mail.info.*)

~[user@host]if zgrep poppy mail.info.1.gz; then echo yes; else echo no; fi
no
~[user@host]if zgrep poppy mail.info.2.gz; then echo yes; else echo no; fi
no
~[user@host]if zgrep poppy mail.info.1.gz mail.info.2.gz; then echo yes; else echo no; fi
yes
~[user@host]


So, as you see, when grep has more than one file argument, its exit status is true. I don't know why this is, but you can fix it with something like:

if gunzip -c mail.info* | grep "Login: poppy"; then echo yes; else echo no; fi


So the wildcard expansion is done for the arguments to gzip, and grep checks stdin for your usernames. But you'll need to make a special case in your script for the non-zipped logfiles, or figure out a more elegant way of doing it.

R Estrada 12-15-2006 12:56 PM

I suggest trying this. You can adjust the find command to include other directories and files.

for i in `find /var/log/ -name dovecot.\*.log\*`
do
for user in `cat checklist`
do
if grep "Login: $user " $i >/dev/null 2>&1
then
echo "$user has logged on"
else
echo "$user has NOT logged on"
fi
done
done

HTH.
Rey


All times are GMT -5. The time now is 05:00 AM.