Sometimes, you need to count the length of time each user logs on. I took a lot of time when I first started this thing. Mainly I used the server too many users, there are more than 1000 people, write a good program to execute nearly half an hour before the statistics are completed. The server I use is Debian, the kernel version is 2.6.32
Server login module using the {pam+mysql database mode, each user has a group of attributes, this attribute is class, I wrote the script is to class to classify.
To make statistical data, it is natural to have data sources first. There is a file in Linux that holds all user login information, which is/var/log/wtmp. This file is a binary file that executes the last command, and you can see the following image information:
In the figure above, because the user name is too long, you can use the LAST-W command to print out all the user names. The last column in the image above is the length of the login, all we have to do is find the same username and then add the last column to the length.
Our program can initially use the "last-w >> data.file" command to redirect data to Data.file, then read data.file files and parse data.file files.
As we can see, the Data.file file is divided into 10 segments per line, so use:
Whie read A B C D E F G H I J
do
processing code done
< Data.file
Thus, the variable J gets the data in the form of: (00:00). But we need to get the data out without other characters such as parentheses. So we have to use some common tools. Here awk is a very good tool:
Awk-f ' A ' {print $} ' file
For example, the code above is to remove and print all the data from the character ' A ' in each line of the file, and:
Awk-f ' A ' {print $} ' file
is to remove and print all the data after the character ' a ' in each line in the file. We're going to take the data out of the variable J and we can do this:
1. Remove all data prior to ') ';
2. To remove the ' (') data;
3. The data before the ': ' is taken out, the unit of this data is an hour;
3. After the ': ' Data is taken out, the unit of this data is minutes.
Reference code:
t=$ (echo $J | awk- f ') ' {print} ')
p=$ (echo $t | awk- f ' (' {print $} ')
(hour=10#$ (Echo $p | Awk- F ': ' {print '} '))
((min=10#$ (echo $p | awk- f ': ' {print $} '))
Among them, the "10#" used in hour and min two variables is to cast the data to 10, rather than octal, resulting in an arithmetical error.
Now the time and the points have been taken out, but only the operation can be. as follows for my code, the deficiencies, because it is a temporary write code, may be a bit messy, inadequacies, but also please point out:
#!/bin/bash ############## # result File:time_count_file # Function:count User login Time ############## # Dir of List dir_list= "/home/class/" #data file data_file=$ (date +%s) _data_file #Result file Result_file=count_file last-w Gt $DATA _file gain_class= ' ls $DIR _list |
grep ' for class in $Gain _class do if [!-d "$DIR _list$class/by_id"];then continue
Fi echo $class >> $RESULT _file for number_student in $ (ls "$DIR _list$class/by_id") do hour_t=0 min_t=0 gain_data= ' grep $number _student $DATA _file ' for J-$Gain _data do hour=0 min=0 t
=$ (echo $J | awk-f ') ' {print $} ') p=$ (echo $t | awk-f ' (' {print $} ')
((hour=10#$ (echo $p | awk-f ': ' {print} ')) ((min=10#$ (echo $p |Awk-f ': ' {print $} ')) if ["$hour" = ""];then If ["$min"
= = "" "];then continue fi
Fi hour_t=$ (($hour _t+ $hour)) min_t=$ (($min _t+ $min)) #echo $hour + $min: $t #echo "" $hour $min >> $RESULT _file do
NE if [$min _t-ge];then hour_t=$ (($hour _t+ $min _t/60)) min_t=$ (($min _t-($min _t/60) *60)) fi time_he=$ (60* $hour _t+ $min _t)) echo "
"" $number _student Time: $time _he ">> $RESULT did done rm $DATA _file