Bash script to boot ssh users who log in more than once

Discussion in 'Programming/Scripts' started by breakaway, Feb 29, 2008.

  1. breakaway

    breakaway New Member

    Hello,

    I am currently writing a bash script that checks if a user has logged in more than once, by checking the output of 'ps x' The output is processed so only two columns of data are available - the PID and the username. If the script finds that two users (with the same username) are logged in, both the users PIDs should be passed to the 'kill' command so they both get disconnceted. I'm slowly getting there:

    Code:
    #!/bin/bash
    
    declare users=`ps x | grep priv | tr -s " " | cut -f 1,6 -d ' '`
    
    # Main Loop
    # if [ $user1 == $user2 ]
    #       then echo "Match found, disconnecting user '$user1'"
    # fi
    
    echo $users
    
    # Quit cleanly
    exit
    Right now, the script just prints out the current users and their PIDs. Unfortunately I don't know how to go any further due to my lack of experience / knowledge. Any help on how to compare every username to every other username, and extract PIDs if/when matches are found would be highly appreciated.

    PS I am aware that there is a way to limit concurrent logins, and this is not what I want. I want both users to be D/Cd.
     
    Last edited: Feb 29, 2008
  2. topdog

    topdog Active Member HowtoForge Supporter

    have you tried
    Code:
    if [ "$user1" = "$user2" ]; then
    But that will match "" as well, you possibly need to check if the $user1 variable is not empty first.
     
  3. breakaway

    breakaway New Member

    Hello,

    No I have not tried that, becuase

    I don't know how to actually read the users / PIDs into a variable properly to begin with.
     
  4. topdog

    topdog Active Member HowtoForge Supporter

    Code:
    pids=$(ps ax| grep sshd | grep "@pts/" | awk '{ print $1 }')
    users=$(ps ax| grep sshd | grep "@pts/" | awk '{ print $6 }' | sed -r "[email protected]\/[0-9]?//")
    YMMV
     
  5. breakaway

    breakaway New Member

    Hello topdog, thanks for the reply. I've already figured out how to actually pull out the usernames and PIDs.

    pids=$`ps x | grep priv | tr -s " " | cut -f 1 -d ' `
    users=$`ps x | grep priv | tr -s " " | cut -f 6 -d ' '`

    My problem is with actually processing them. I am unfamiliar with how to write loops etc.

    TIA!
     
  6. topdog

    topdog Active Member HowtoForge Supporter

    Code:
    #!/bin/bash
    declare -a array1
    declare -a array2
    users=$(ps x | grep priv | tr -s " " | cut -f 6 -d ' ')
    pids=$(ps x | grep priv | tr -s " " | cut -f 1 -d ' ')
    array1=($users)
    array2=($pids)
    
    for i in $(seq 0 $((${#array1[*]} - 1))); do
            testvalue=${array1[$i]}
            for x in $(seq 0 $((${#array1[*]} - 1))); do
                    if [ "$x" = "$testvalue" ]; then
                            kill -9 ${#array2[$i]}
                    fi
            done
    done
    
     
  7. breakaway

    breakaway New Member

    Thanks topdog! Unfortunately it appears this script is not running properly :\ I have several users logged in like so:

    416 breakaway
    30459 breakaway
    30490 breakaway
    30521 vent
    30553 devon
    32743 xerxes

    But it didn't kill the 3 'breakaway' users :\
     
  8. topdog

    topdog Active Member HowtoForge Supporter

    Okay i did not test, but i have just checked it seems like your commands to check the users does not work.
     
  9. topdog

    topdog Active Member HowtoForge Supporter

    Code:
    #!/bin/bash
    declare -a array1
    declare -a array2
    pids=$(ps ax| grep sshd | grep "@pts/" | awk '{ print $1 }')
    users=$(ps ax| grep sshd | grep "@pts/" | awk '{ print $6 }' | sed -r "[email protected]\/[0-9]?//")
    array1=($users)
    array2=($pids)
    
    for i in $(seq 0 $((${#array1[*]} - 1))); do
            testvalue=${array1[$i]}
            for x in $(seq 0 $((${#array1[*]} - 1))); do
                    intestvalue = ${array1[$x]}
                    if [ "$intestvalue" = "$testvalue" ]; then
                            kill -9 ${#array2[$i]}
                    fi
            done
    done
     
  10. topdog

    topdog Active Member HowtoForge Supporter

    Sorry that has a bug it could kick out all the users let me perfect it first.
     
  11. topdog

    topdog Active Member HowtoForge Supporter

    Please test before use in a production environment.

    Code:
    #!/bin/bash
    declare -a array1
    declare -a array2
    pids=$(ps ax| grep sshd | grep "@pts/" | awk '{ print $1 }')
    users=$(ps ax| grep sshd | grep "@pts/" | awk '{ print $6 }' | sed -r "[email protected]\/[0-9]?//")
    array1=($users)
    array2=($pids)
    
    for i in $(seq 0 $((${#array1[*]} - 1))); do
            testvalue=${array1[$i]}
            count=0
            for x in $(seq 0 $((${#array1[*]} - 1))); do
                    intestvalue = ${array1[$x]}
                    if [ "$intestvalue" = "$testvalue" ]; then
                            let count=count+1
                            #check if the name has appeared more than one and kill
                            if [ $count -gt 1 ]; then
                                    kill -9 ${#array2[$i]}
                            fi
                    fi
            done
    done
    
     

Share This Page