LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Red Hat (http://www.linuxquestions.org/questions/red-hat-31/)
-   -   Log off all users other than root (http://www.linuxquestions.org/questions/red-hat-31/log-off-all-users-other-than-root-501974/)

Skywing 11-15-2006 06:09 PM

Log off all users other than root
 
Hey everyone, I'm having a bit of trouble with this task ive been given. I basically need a way to log out every user logged into the system other than root, I dont need it to target any set of specific users, just every single one OTHER than root. All the users are using BASH and this is in RHEL4 if that makes any difference, and I'm sure that this can be done with a simple script but I've been killing myself over trying to get this done. Can anyone PLEASE be of some assistance? :cry:

slakmagik 11-15-2006 06:30 PM

Task or homework?

Skywing 11-15-2006 06:40 PM

Quote:

Originally Posted by digiot
Task or homework?

task, unfourtinately it has been passed down to me since im the only person that has even the slightest bit of Linux knowledge. After searching around for a bit would doing

Code:

skill -KILL -v /dev/pts/*
do what im looking for?

jschiwal 11-15-2006 06:58 PM

You could get a list of logged in users using the "who -u" command.

slakmagik 11-15-2006 07:01 PM

Quote:

Originally Posted by Skywing
task, unfourtinately it has been passed down to me since im the only person that has even the slightest bit of Linux knowledge.

Ah, okay. :)

Quote:

After searching around for a bit would doing

Code:

skill -KILL -v /dev/pts/*
do what im looking for?
Don't think so - you're looking to log people out, which would usually be from a tty and there's nothing there to exclude root.

To be honest, I don't know the answer. I feel like there should be something simple and direct like the skill example. Best thing I can think of (excuse my horrible awk) would be
Code:

#!/bin/bash
ps aux | awk '
! /^root/ {
    if ($11 ~ /-bash/)
        print $2
}
' | xargs kill # maybe with a '-9'

Untested and kinda rude, but I think it might do it. Probably a way to do it with just ps flags and kill.

-- Just saw jschiwal's post in the preview screen - so maybe who -u | awk '! /root/{ print $6 } | xargs kill

Skywing 11-15-2006 07:12 PM

Quote:

Originally Posted by digiot
Ah, okay. :)



Don't think so - you're looking to log people out, which would usually be from a tty and there's nothing there to exclude root.

To be honest, I don't know the answer. I feel like there should be something simple and direct like the skill example. Best thing I can think of (excuse my horrible awk) would be
Code:

#!/bin/bash
ps aux | awk '
! /^root/ {
    if ($11 ~ /-bash/)
        print $2
}
' | xargs kill # maybe with a '-9'

Untested and kinda rude, but I think it might do it. Probably a way to do it with just ps flags and kill.

-- Just saw jschiwal's post in the preview screen - so maybe who -u | awk '! /root/{ print $6 } | xargs kill

alright, thanks guys, ill give these a try and report back. :)

Skywing 11-15-2006 08:07 PM

well i tried those and none worked, but i found another possible solution, if i do the following

Code:

ps -ef | grep -v root
itll list every process that ISNT being run by root, so how can i go about telling the system to kill every process that it finds isnt being run by root?

slakmagik 11-15-2006 08:31 PM

Well, the PID is in the second field, so extract that and kill it. Not sure it's necessary to kill every process, since kicking out the parent should take down the rest, but either way.

I have a couple-three boxes I could test it on, but I've got too many things open I don't want to lose my place in. :) What happened with the above commands? Because that's essentially what they do - isolate the PIDs and attempt to kill them. How they failed might be instructive. Failed with 'kill -9', too?

Skywing 11-15-2006 08:58 PM

Quote:

Originally Posted by digiot
Well, the PID is in the second field, so extract that and kill it. Not sure it's necessary to kill every process, since kicking out the parent should take down the rest, but either way.

I have a couple-three boxes I could test it on, but I've got too many things open I don't want to lose my place in. :) What happened with the above commands? Because that's essentially what they do - isolate the PIDs and attempt to kill them. How they failed might be instructive. Failed with 'kill -9', too?

crap, forgot to try with the -9 :(

im a bit of a n00b when it comes to scripting but how do i go about extracting and killing the second field?

slakmagik 11-15-2006 09:40 PM

There are probably a zillion ways - one is basically like I had it above (since awk is a bit large but very handy with tabular data due to its field handling):
ps h -ef | grep -v root | awk '{ print $2 }' # print the second field of the input records (lines)
or
ps -ef | egrep -v 'root|UID' | awk '{ print $2 }'
or dispensing with grep
ps h -ef | awk '! /^root/{ print $2 }'
which gets us basically back to where we were. :) Could also use various 'cut's and 'sed's and so on, I guess. If that doesn't get it, maybe this isn't the right route at all - something to do with tackling getty or init directly. Why does root need to stay logged on? A lot more would go offline than just the users, but just doing a 'telinit 1' almost seems like the handiest, though a bit overkill. ;)

jschiwal 11-15-2006 09:42 PM

If you are looking at processes, be sure you don't also kill system process. There are also system users.
You can use the "users" command to get a list of users who are currently logged in. The names are not uniq however, as a user may have more than one shell going.
This will give you a list of unique non-root users:
users | tr ' ' '\n' | sort | grep -v root | uniq

I think that if you sent a SIGHUP signal to the user process with a pts or tty in the processes list that would do what you want.

This will supply a list of such processes:
for username in $(users |tr ' ' '\n' |grep -v root|sort|uniq); do echo "user: $username"; ps -u $username; done | grep -e pts -e tty | cut -f2 -d' '

This might do the trick:
Code:

for process in $( for username in $(users |tr ' ' '\n' |grep -v root|sort|uniq); do ps -u $username; done | grep -e pts -e tty | cut -f2 -d' ' );
do
  kill -SIGHUP $process
done


slakmagik 11-15-2006 10:01 PM

Quote:

Originally Posted by jschiwal
If you are looking at processes, be sure you don't also kill system process. There are also system users.

Good catch. I was thinking of that originally when I was trying to kill '-bash' login shell processes. That would remove system processes from the equation. But as the thread wandered, I forgot. :(

Skywing 11-16-2006 09:04 AM

wow, thanks for all the help guys, I really appreciate it, I will give all these a try once I get back to the location tonight and report back results.

Skywing 11-16-2006 03:08 PM

I havent tested it yet, but I figured I would ask anyway, would the following suffice?

Code:

ps -ef | grep bash | grep -v grep | grep -v root | awk '{system("kill -n 9" $2)}'

slakmagik 11-16-2006 03:50 PM

That would leave you open to killing system processes as jschiwal pointed out. Also, if you have pgrep, try using that. It never matches itself, so you don't have to 'grep -v grep'. Also, awk can match ^root, so you could dispense with that 'grep -v'. And awk will concatenate the system function - think it'd need to be "kill -n 9 " (note space).

All this is dancing around the same thing, though - if any of this would work, I don't see why the first suggestion wouldn't. And if it didn't, it seems likely these would fail, too.

Which got me to thinking: I just created a user 'test' and logged 'him' into a second X session and ran my first script as root, just modified to spare both me and root. :)
Code:

#!/bin/bash
ps aux | awk '
! /^root|^j/ {
    if ($11 ~ /-bash/)
        print $2
}
' | xargs kill -9

I'm still here and root's still here, but 'test' is knocked out. So you must not have been running the script as root or made a typo or something, because it works here.

-- Actually, a plain 'kill' doesn't seem to work, but a 'kill -9' is probably literally overkill. It left an X lock file behind on one test. (I was running X just for a simple way to have multiple processes to knock out above the login shell.) So this may be better (final take (I hope :))):
Code:

ps aux | awk '! /^root/{ if ($11 ~ /-bash/) print $2 }' | xargs kill -1
Seems to work and seems to let processes clean up.


All times are GMT -5. The time now is 07:36 AM.