Bourne Shell script - log for users loggin on and off

Hello all, I'm new to shell scripting and want to make a script that I can write to log the users logging on and off the a unix system.

I have had a good look over the past few days to crack it, I think I am getting close.

I want a script that runs an infinite loop to check every 5 seconds to report on who logs into and who logs out of the unix system.

This is a example of the output I would like:

The current users are:
abc1
rv0
sxu
tgray

No user has logged in/out in the last 5 seconds.

No user has logged in/out in the last 5 seconds.

User rsmith has logged in.

No user has logged in/out in the last 5 seconds.

User abc1 has logged out.

No user has logged in/out in the last 5 seconds.

I am using
who | awk '{print $1}' | sort > temp1
to get the users logged on and saving that into a temp file.

and have a while loop set up like this which will run each 5 seconds.

while true
do
.
.
.
.
.
sleep 5
done

The problem I'm having is, I can't work out how to compare the current users logged in to the users that have previously logged in.

I thought of making a second temp file that stores the current users then using:
cmp temp1 temp2
to look at the difference. problem is it gives me an output saying "file differs at character 42, line 6" and that isn't helping me much as I would like to then display that users name but not sure how to print that position in the file (or just a line for that matter).

The test to see if the user has logged on or off is easy, as it is only a couple of if statements.

like if user is in temp1 but not in temp2 then the user has logged out and vice versa.

I have been looking at this for a while now and am going around in circles. any code fragments, help or written shell scripts :slight_smile: would be greatly appreciated.

Thanks in advance

Noodle

Use the 'comm' utility. The -13 and the -23 options will give you what you want. Check the man page for details.

you are quite the life saver, thank you very much.

Also is there a quick command you can use for a an if statement to see if the files differ?

if [statement here].

I had a look at the cmp utility and the exit status was 0 is the files were identical and 1 if the files were diferent. but I couldn't get the exit status printed to screen.

Thanks in advance

Hm. Use the diff command. The exit code for diff is 0 if the files are identical, and 1 if they are not.

OK, this is what I have got now, not srue where I have gone wrong. it says I have a syntax error on line 30; ';;' unexpected? any ideas? I thought these were needed for the case to work

#! /bin/sh

echo "The current users are:"

who | awk '{print $1}' | sort > temp1
cp temp1 temp2
more temp1

while true
do
	who | awk '{print $1}' | sort > temp2
	cmp -s temp1 temp2

	case "$?" in
	
	0)
		echo "No user has logged in/out in the last 5 seconds."
		;;
	
	1)
		user=`comm -23 temp1 temp2`
		file=`grep $user temp1 temp2 | cut -c 1-5`

		if [ $file = "temp1" ]
			echo "User "$user" has logged out."
			
		
		if [ $file = "temp2" ]
			echo "User "$user" has logged in."
		;;
		
	esac
	
	rm temp1
	mv temp2 temp1
	
	sleep 5

done
       if list then list [elif list then list] ... [else list] fi
              If the exit status of the first list is zero, the second list is
              executed; otherwise the list following the elif, if any, is exe-
              cuted with similar consequences.  If all the lists following the
              if and elifs fail (i.e., exit with non-zero  status),  the  list
              following the else is executed.  The exit status of an if state-
              ment is that of non-conditional list that  is  executed;  if  no
              non-conditional list is executed, the exit status is zero.

thanks for the reply, but i'm still a little stuck.
Vgersh99 would you mind rewriting my if statements in there correct syntax for me as i still can't get them working right.

Thanks in advance

        if [ $file = "temp1" ]; then
            echo "User "$user" has logged out."
        fi
            
        
        if [ $file = "temp2" ]; then
            echo "User "$user" has logged in." 
        fi

solution::try this code

#! /bin/sh 

echo "The current users are:" 

who | awk '{print $1}' | sort > temp1 
cp temp1 temp2 
more temp1 

while true 
do 
    who | awk '{print $1}' | sort > temp2 
    cmp -s temp1 temp2 

    case "$?" in 
     
    0) 
        echo "No user has logged in/out in the last 5 seconds." 
        ;; 
     
    1) 
        user=`comm -23 temp1 temp2` 
        file=`grep $user temp1 temp2 | cut -c 1-5` 

        [ $file = "temp1" ] && echo "User "$user" has logged out." 
             
         
        [ $file = "temp2" ] && echo "User "$user" has logged in." 
        ;; 
         
    esac 
    rm temp1 
    mv temp2 temp1 
    sleep 5 

done 

If you have unix accounting turned on you can use the last command. The history for user logins would stay until you roll the file. We accumulate the history by day per user then roll the log to start over.

user1 pts/6 mypc1 Fri Sep 8 08:15 still logged in
user2 ftp mypc2 Fri Sep 8 08:05 - 08:05 (00:00)

thanks heaps for the help guys. works just how I wanted :slight_smile:

Here is the Out put of the Code for #9 when you login from other terminal it throw error similarly at the time of logout ???

$ ./u1.sh
The current users are:
coetest1
coetest1
root
root
root
root
root
root
root
No user has logged in/out in the last 5 seconds.
No user has logged in/out in the last 5 seconds.
No user has logged in/out in the last 5 seconds.
./u1.sh[22]: temp1: unknown test operator
./u1.sh[25]: temp1: unknown test operator
No user has logged in/out in the last 5 seconds.
No user has logged in/out in the last 5 seconds.

what do you mean by unknown test operator ??

I guess instead of user=`comm -23 temp1 temp2`
it should be user=`comm -13 temp1 temp2` ### 23 should be 13 ??

check my suggestion

yeah I'm getting the same error now. it doesn't work with the -13 option in comm either. any suggestions?

put double quotes aroung $file in the test statements.