logout-other.sh
#!/usr/bin/env bash

# This script logs out another user.
# Works only on Mac. REMEMBER to run with sudo.
#
# Exit values:
#   0 = Command run succesfully
#   1 = Wrong number of arguments
#   2 = No defined logged on user found
#   3 = Terminating the loginwindow process failed
#   4 = (Warning) Too many processes are running
#   5 = Terminating a process failed

if [ $# -ne 1 ]; then
    echo "Usage: $0 ACCOUNTNAME" 1>&2
    exit 1
fi

NAME=$1
LOGWIN=".*\/loginwindow.app\/.+\/loginwindow"
LOGWINPID=`ps auxw | grep -w $NAME | awk '$1 ~ /'$NAME'/ && $11 ~ /'$LOGWIN'/ {print $2}'`
if [ ${#LOGWINPID} -eq 0 ]; then
    echo "No logged on user \"$NAME\" found." 1>&2
    exit 2
fi

CHKOUTMSG1="Run the following command to check the situation:"
CHKOUTMSG2="    ps auxw | grep -w '$NAME'"

kill -9 $LOGWINPID
if [ $? -ne 0 ]; then
    echo "loginwindow could not be killed. Remember to use sudo." 1>&2
    echo "$CHKOUTMSG1" 1>&2
    echo "$CHKOUTMSG2" 1>&2
    exit 3
fi

# Killing the rest of the processes is attempted twice to fight against watchdogs.
# Seems that at least Spotlight is relaunched automatically some time after
# killing the loginwindow process.
for ((i=0; i < 2; i++)); do
    # Waits a little to make sure that loginwindow process has died
    # and killed all it's child processes.
    sleep 2

    PIDs=(`ps auxw | grep -w $NAME | awk '$1 ~ /'$NAME'/ {print $2}'`)

    if [ ${#PIDs[*]} -gt 100 ]; then
        echo "There are probably too many processes running for user \"$NAME\"" 1>&2
        echo "$CHKOUTMSG1" 1>&2
        echo "$CHKOUTMSG2" 1>&2
        exit 4
    fi

    for pid in ${PIDs[*]}; do
        kill -9 $pid
        if [ $? -ne 0 ]; then
            echo "A process could not be killed." 1>&2
            echo "$CHKOUTMSG1" 1>&2
            echo "$CHKOUTMSG2" 1>&2
            exit 5
        fi
    done
done

echo "\"$NAME\" was logged out succesfully."
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License