Help Me - how to use the who command with awk and array.
Hi, I am new to the forum and I hope someone can help me. I had to create a script to kill users off the system with exception of MIS user group. I have most of it but, I can not fiqure out how to use the who command with awk and an array as the user names.
Here is what I have so far: ### create file with all users in the "mis" group /usr/bin/getent group mis | /usr/bin/awk -F: '{print $4 }' > killtest.txt ### Do for the number of users in the group for i in `seq 1 $(awk -F, '{ total = total + NF }; END {print total}' killtest.txt)`; do awk -v I=$i -F, '{print $I }' killtest.txt >>killtest.dat done users=($(awk '{print $1}' killtest.dat)) echo ${users[*]} who -u | awk -v users="$users" '{ if ($1!="root" && $1!=users[*]) print $1 $6 }' > killthem.dat My problem is the who command how do I get the list of users not to be included in my list. This should print the username and the process id. exp output: name19998 name23455 name23354 By the way I am doing this in Bash. Thank you |
Hi djs515!
I'm not quite sure how you're using the group and passwd "databases" on your system. If I were going to use a mix of bash and awk, I might do something like the following to get a list of users in a particular group. Given what might be a difference in the way getent works on our systems, what I'm about to illustrate is put together to be run as root, and just access the text files directly. You can interpret it to apply it in the context of however your getent works. Since I don't necessarily have an mis group, I'll just use the users group, so I can have actually run the code and make sure it works on my system. Code:
group_id=`egrep '^users:' /etc/group | cut -d: -f3-3` Code:
group_id=`egrep '^users:' /etc/group | cut -d: -f3-3` |
Thanks for the reply but confused
I am confused why you are using the /etc/passwd in the awk command?
Also, the statement: group_id=`egrep '^users:' /etc/group | cut -d: -f3-3’ #-- Does not work for me I do not have /etc/group on my system The command I am using works great: group_id=($(/usr/bin/getent group killemall | /usr/bin/awk -F: '{print $4 }')) #-- This returns all the users in the mis group comma , delimited. name1,name2,name3 I don’t see where you use this array group_id in the awk? What I am trying to do is create a file with all the users who are currently logged on and not include the users in the MIS group which now = group_id. My end results will be the username and process id. I am able to do this without an array for one name but I can’t figure out how to do it for a list of names. This is the script I have to kill off all users except for root and me and works great: me=$(logname) who -u | awk -v me="$me" '{ if ($1!="root" && $1!=me) print "/usr/bin/sudo kill -9 " $6 }' > /bin/kill.dat chmod 744 /bin/kill.dat /bin/kill.dat Hope you can help. Thank you |
I am very sorry. I misinterpreted a variety of things about your question.
I think I understand much better now. On the Linux system I am using, I was able to take a bash array of users and get it into an awk array of users like this: Code:
( echo ${users[*]} ; who -u ) | awk ' The awk "in" operator checks for a match amongst the indexes of the array, not the values of the elements. So the value of the array element isn't meaningful in this case. Each user name is used as an index of an array element; I just set the value of the array element to a arbitrary constant, to create the array element. On my system the output of "who -u" looks like this: Code:
user pts/6 Aug 15 18:39 19:13 20226 Code:
### Do for the number of users in the group |
Still confused
Now I get a syntax error near unexpected token 'done'
This is what I have now: ### create file with all users in the "mis" group /usr/bin/getent group killemall | /usr/bin/awk -F: '{print $4 }' > killtest.txt ### Get total number of users numofusers=$(awk -F, '{ total = total + NF }; END {print total}' killtest.txt) who -u | awk '{ if ($1!="root" && $1!=(for i in $numofusers; do; awk -v I=$i -F, '{print $I } ; done) print $1 $6 }' > killthem.dat I must be missing something, I feel like we are so close. hope u can help, I need this before month-end. Thank you so much for all your replys it is really appreciated :) |
Tried this too
I also tried this but it didn't exclude the names in the killtest.txt which has the names of the users to exclude form the who list in killthem.dat
chmod 744 killtest.dat rm killtest.dat ### create file with all users in the "killemall" group /usr/bin/getent group killemall | /usr/bin/awk -F: '{print $4 }' > killtest.txt ### Do for the number of users in the group # since users will be appended to killtest.dat first make sure the file is empty for i in `seq 1 $(awk -F, '{ total = total + NF }; END {print total}' killtest.txt)`; do awk -v I=$i -F, '{print $I }' killtest.txt >>killtest.dat done ( echo ${users[*]} ; who -u ) | awk ' ( NR == 1 ) { for ( field_num=1 ; field_num <= NF ; field_num++ ) { users[ $field_num ] = 1 ; } } ( NR > 1 ) { if ( ($1!="root") && ! ( $1 in users ) ) print $1 $6 }' > killthem.dat I hope you can see what I am doing wrong. Thank again!!! |
djs515, in your most recent message, I don't see the code that creates the bash array. Did you remove your code that creates the bash array?
Code:
users=($(awk '{print $1}' killtest.dat)) Also, I would suggest that you always refer to files in the same way. That is, if you need to include the full path for a file such as /home/dsantore/killtest.txt then you should always use the full path for the file, to make absolutely sure you are using the same file. You probably shouldn't use /home/dsantore/killtest.txt in one place, and just killtest.txt in another place. |
Try setting the top of the script to
Code:
#!/bin/bash |
Fantastic – Thank you so much
Got it Thanks you so much, I am so happy I joined this forum. You are all so smart. A SPECIAL THANKS TO KAKAKA!!!
I am going to post what I have that works in case anybody else needs to do this. This code will kill off all users except users in a specified group on the system. I needed to do this for month end. To kill off all user except the users in the MIS group. # KILLEMALL - Kill off all users on the system except users in MIS group # chmod 744 /bin/groupusers.dat rm /bin/groupusers.dat ### Create a file with all users in the "mis" group -- Change to what ever group you want to exclude /usr/bin/getent group mis | /usr/bin/awk -F: '{print $4 }' > /bin/groupusers.txt ### Do for the number of users in the group for i in `seq 1 $(awk -F, '{ total = total + NF }; END {print total}' /bin/groupusers.txt)`; do awk -v I=$i -F, '{print $I }' /bin/groupusers.txt >>/bin/groupusers.dat done ### Move users to exclude from kill in to an array which will be used as an index for awk users=($(awk '{print $1}' /bin/groupusers.dat)) ( echo ${users[*]} ; who -u ) | awk ' ( NR == 1 ) { for ( field_num=1 ; field_num <= NF ; field_num++ ) { users[ $field_num ] = 1 ; } } ( NR > 1 ) { if ( ($1!="root") && ! ( $1 in users ) ) print "/usr/bin/sudo kill -9 " $6 }' > /bin/kill.dat chmod 744 /bin/kill.dat /bin/kill.dat exit If you want to see the user name just add $1 in the print of the awk. Just remember to take it out other wise it will error out. Thanks again!!!! |
All times are GMT -5. The time now is 05:07 AM. |