Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!


Click here to return to the '10.4: Tiger version' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
10.4: Tiger version
Authored by: mzs on Apr 20, '06 11:00:29AM
mbdayton posted that this no longer works in Tiger. I have the following working in 10.4.

I have this script: ~/bin/fus


#!/bin/sh
# Fast User Switching from the command line

CGSession='/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession'

case "$#" in
    0)
        # display login screen
        exec "$CGSession" -suspend
        exit
        ;;
esac

# No reason to display the login panel for the current user
case "$1" in
    "$USER" | "$UID")
        exit 0
        ;;
esac

# can pass in a (short) username or userid
id=`/usr/bin/id -u "$1"` || exit

# display login panel for user
exec "$CGSession" -switchToUserID "$id"
It is basically the same code as before but it can take a userid (501 for example) or username (unix short name in Mac parlance) as an argument. It also first checks to see if you are changing to the current user.

Then I create a symlink to ~/bin/fus in ~/Library/Scripts:


ln -s ~/bin/fus ~/Library/Scripts/Login\ Window
Now I can select "Login Window" from the AppleScript menu to switch to a different user.

To be able to switch to some particular user without going through the Login Window first, I make this script too: ~/Library/Scripts/.fus


#!/bin/sh
exec "$HOME"/bin/fus `/usr/bin/basename "$0"`
It starts with a dot (.) so that it does not show-up in the AppleScript menu. If you make links to .fus it will call fus with whatever name you gave to the link. (Remember that you need to make both fus and .fus executable.)

Now for every user that I want to be able to switch to directly from the AppleScript menu I do the following in the Terminal:


ln ~/Library/Scripts/.fus ~/Library/Scripts/foo
Where "foo" is the username of the user. It is very important that you make a hardlink instead of a symlink because for whatever reason when you run the script from the AppleScript menu the symlink is resolved to the .foo file and then the .foo script has no way of knowing which user to switch to.

Then from the AppleScript menu I can choose "foo" and up pops the panel asking for the user password.

[ Reply to This | # ]

Zombie processes
Authored by: mzs on Apr 20, '06 01:17:04PM
I have been using this for a quile and I just noticed that in Tiger at least this approach leaves many zombie process around beacause SystemUIServer never reaps the exit status of the .fus and fus shell scripts.

  9608 /System/Library/CoreServices/SystemUIServer.app/Contents/MacOS/SystemUIServer -psn_0_91226113
    19123 (sh)
    19224 (CGSession)
    19229 (CGSession)
    19249 (sh)
    19253 (sh)
    19256 (sh)
    19259 (sh)
    19262 (sh)
    19273 (sh)
    19276 (CGSession)
    19283 (CGSession)
    19302 (CGSession)
    19332 (CGSession)
    19341 (CGSession)
    19389 (CGSession)
    19035 (CGSession)
That is a bug. Here is a work around. If the scripts in the ~/Library/Scripts folder are AppleScripts instead of Bourne shell scripts, then there is no exit status to reap, and hence no zombie processes remain.

First remove these files (remember that Login Window is a link to fus so it is important to delete these first):


rm ~/Library/Scripts/Login\ Window ~/Library/Scripts/.fus
Now for every user that you created a link to .fus for, do a command like this but replace "foo" with the approppriate username:

rm ~/Library/Scripts/foo
Create this AppleScript ~/Library/Scripts/.fus.scpt:

-- get the home dir
set H to quoted form of (system attribute "HOME")

-- get name of script
tell application "Finder" to set N to name of (path to me)

-- escape special characters
set N to quoted form of N

-- call fus to switch user
do shell script H & "/bin/fus `/usr/bin/basename " & N & " .scpt`"
Again the name begins with a dot (.) so that it does not appear in the AppleScript menu. This AppleScript calls fus with its own name (minus the .scpt extension) in a similar vein as .fus originally worked.

Now we need to create the "Login Window" script in the AppleScript menu. It too cannot be a link to a Bourne shell script anymore because there will be zombie processes remaining. But since the name trick is not being played with it, this AppleScript is very straigh forward. Here is my '~/Library/Scripts/Login Window.scpt':


-- get the home dir
set H to quoted form of (system attribute "HOME")

-- call fus to get Login Screen
do shell script H & "/bin/fus"
Remember to make links to .fus.scpt for each user you want to switch to directly like so:

ln ~/Library/Scripts/.fus.scpt ~/Library/Scripts/foo.scpt
Now you would have an entry in the AppleScript menu for the user "foo". The ".scpt" extension will not show-up in the AppleScript menu so you might as well use it. If you do not want to use the extension that is fine too, the .fus.scpt will deal with that as well. Just do not use any other extension because then it will not work.

[ Reply to This | # ]