If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Data Access, Manipulation & Batch Languages > Unix Shell Scripts > unix shell

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 04-02-04, 10:05
james bell james bell is offline
Registered User
 
Join Date: Apr 2004
Posts: 3
Talking unix shell

i require a utility that identifies all users currently logged into the system. It should create a file called logfile which contains a list of usernames together with a count of how many login sessions they are currently running, for example

coc9io : 1
hbh8jd : 3
dg7hy : 1
root : 4

it should also print to a standard output message to the form

Total User: hbh8jd (3 sessions)

for each user with more than 2 current login sessions.

if possible can you you use comments so that i understand the code better

thanks very much

james bell
Reply With Quote
  #2 (permalink)  
Old 04-02-04, 10:42
aigles aigles is offline
Registered User
 
Join Date: Jan 2004
Location: Bordeaux, France
Posts: 319
a possible way to do the work : who + awk
__________________
Jean-Pierre.
Reply With Quote
  #3 (permalink)  
Old 04-02-04, 11:03
Hobbletoe Hobbletoe is offline
Registered User
 
Join Date: Mar 2004
Posts: 3
Try ...

echo ' ' >> logfile
date >> logfile
for name in `who | cut -f1 -d' ' | sort -u`
do
name_count=`who | grep -c ${name}`
if [ ${name_count} -gt 2 ]
then
echo ${name}':'${name_count} >> logfile
echo 'Total User:'${name}' ('${name_count}' sessions)'
fi
done

This is done in sh. The only problem that I can see, and don't quite know how to correct would be if you have someone with a name like jon and then a jones, as jon would be counted as jones as well.

As for the commands who gives you a list of each person's sessions. Since their name is the first column in who, when you cut the response, you only want the first column (-f1), and it is delimited with a space (-d' '). The sort -u makes sure that you only get the one instance for each person. Without it, you would get something like:

jones:3
jones:3
jones:3

Not what you want, I'm sure. After you have your list of users, you need to count each one. So, re do the who command, and pipe it through grep -c (line count). Compare that against what you want (you said more than 2 entries, so I did the -gt 2), and echo out what you want to see.

Oh, and the logfile. I didn't know if you wanted it to be a running logfile, or what, so I made it so that it puts a blank line, and then the date, and the the list of users. Handy if you are wanting to track when folk are on the most or whatever. If this isn't what you want, then I would drop the date command, and change the echo above the for loop to

echo > logfile

> will cause the file to be re-created, while >> causes the file to be appended to.

Hope this helps.

Hobbletoe

Edit: Forgot the logfile ... changed a few other things.

Last edited by Hobbletoe; 04-02-04 at 11:30.
Reply With Quote
  #4 (permalink)  
Old 04-02-04, 11:47
aigles aigles is offline
Registered User
 
Join Date: Jan 2004
Location: Bordeaux, France
Posts: 319
A possible solution with who + awk

Code:
who | \
awk '
# Memorize each user and increment login count 
{
   login[$1]++;
}
# All logged users have been memorized, display result
END {
   # Initialize log file name if not set
   if (LOGFILE == "")
      LOGFILE = "who.log";
   # For each memorized user log and display result
   for (user in login) {
      logcnt = login[user];
      print user ": " logcnt > LOGFILE;
      if (logcnt > 2)
         printf("Total User: %s (%d sessions)\n", user, logcnt);
   }
}
' LOGFILE=/path/to/logfile
__________________
Jean-Pierre.
Reply With Quote
  #5 (permalink)  
Old 04-02-04, 15:50
james bell james bell is offline
Registered User
 
Join Date: Apr 2004
Posts: 3
Red face A possible solution with who + awk

just says Permission denied

not sure why i copied and pasted in
Reply With Quote
  #6 (permalink)  
Old 04-02-04, 16:35
Damian Ibbotson Damian Ibbotson is offline
Padawan
 
Join Date: Jun 2002
Location: UK
Posts: 525
Quote:
This is done in sh. The only problem that I can see, and don't quite know how to correct would be if you have someone with a name like jon and then a jones, as jon would be counted as jones as well.
Use 'grep -wc' ?

Another method would be to use who + cut + uniq +awk...
Code:
who | cut -f1 -d' ' | uniq -c | awk '$1>1{print "Total User: "$2" ("$1" sessions)"}{print $2" : "$1 > "logfile"}'
The above is untested as I don't have access to a Unix box at the minute, so I hope it works. Personally, I prefer JP's pure awk solution but this might be a little easier to get your head round to start with!

You can break the pipeline down to see how this works if you want...

who
who | cut -f1 -d' '
who | cut -f1 -d' ' | uniq -c
Reply With Quote
  #7 (permalink)  
Old 04-03-04, 03:46
aigles aigles is offline
Registered User
 
Join Date: Jan 2004
Location: Bordeaux, France
Posts: 319
Quote:
Originally posted (private message) by james bell
hi mate figured it out

chomd 755

but when i ran the script this came up

dave.sh: awk^J # Memorize each user and increment login count^J{^J login[$1]++;^J}^J # All logged users have been memorized, display result^JEND {^J # Initialize log file name if not set^J if (LOGFILE == "")^J LOGFILE = "who.log";^J # For each memorized user log and display result^J for (user in login) {^J logcnt = login[user];^J print user ": " logcnt > LOGFILE;^J if (logcnt > 2)^J printf("Total User: %s (%d sessions)\n", user, logcnt);^J }^J}^J: not found
hapy:/home/cb3dwa % dave.sh: awk^J # Memorize each user and increment login count^J{^J login[$1]++;^J}^J # All logged users have been memorized, display result^JEND {^J # Initialize log file name if not set^J if (LOGFILE == "")^J LOGFILE = "who.log"^Z^Z
hapy:/home/cb3dwa % dave.sh
dave.sh: awk^J # Memorize each user and increment login count^J{^J login[$1]++;^J}^J # All logged users have been memorized, display result^JEND {^J # Initialize log file name if not set^J if (LOGFILE == "")^J LOGFILE = "who.log";^J # For each memorized user log and display result^J for (user in login) {^J logcnt = login[user];^J print user ": " logcnt > LOGFILE;^J if (logcnt > 2)^J printf("Total User: %s (%d sessions)\n", user, logcnt);^J }^J}^J: not found


any thoughts?
Shell considers that the command name is formed by awk + awk script, this can happen if the quote is misplaced, for example : who | 'awk
Verify and mofify your script :
Code:
who | awk '
# Memorize each user and increment login count 
{
   login[$1]++;
. . . . .
__________________
Jean-Pierre.
Reply With Quote
  #8 (permalink)  
Old 04-18-04, 10:51
james bell james bell is offline
Registered User
 
Join Date: Apr 2004
Posts: 3
Question

hi m8 this code works fine

who | cut -f1 -d' ' | uniq -c | awk '$1>1{print "Total User: "$2" ("$1" sessions)"}{print $2" : "$1 > "logfile"}'

only trouble is i do not understand the $1 and $2

where do they come from and what do they do ?

thanks david w
Reply With Quote
  #9 (permalink)  
Old 04-18-04, 13:56
aigles aigles is offline
Registered User
 
Join Date: Jan 2004
Location: Bordeaux, France
Posts: 319
Within awk program, $n stands for field n of record read from input file.
The output of the 'uniq -c' command in in the form :
number_of_records record
So, in the awk program, $1 is number_of_records and $2 is record (in fact user).

I think that you need to add a sort command in the pipe :
Code:
who | cut -f1 -d' ' | sort | uniq -c | \
awk '$1>1{print "Total User: "$2" ("$1" sessions)"}{print $2" : "$1 > "logfile"}'
__________________
Jean-Pierre.
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On