![]() |
Test to see if anyone is logged on?
Hi
I have a startup script (called by a launch daemon) which goes off to Apple and runs softwareupdate. If a restart is required, I want the machine to restart if no one is logged on. These are lab machines which started around 15 minutes before the first classes. Could someone please point me in the right direction as to how to check if anyone is logged onto the machine. thanks |
Use the w or who commands.
|
Thanks. I looked into those as well as logname. What I can't figure out is how to test to see if they exist.
I want something like :- user=$logname if $user doesn't exist then restart fi If no one is logged in, what does who or logname or return? Zero lengths strings? |
Quote:
Something like last $username and process the result. |
See who owns the console, every time a user logs in they gain ownership of the console, if the console is owned by root then it is at the login window.
example: Code:
admins-imac:~ tlarkin$ ls -l /dev/console | awk '{ print $3 }' |
As with all things *nix, there are several ways to get the same thing ;)
Code:
last -t console | grep "still logged in" |
Quote:
I just prefer the console method, and that is just my opinion. |
Thanks for the replies so far but I know how to get the name of the current logged on user. What I want to know is how to test if anyone is logged on.
At the end of my script, I want this to happen :- if no one is logged on then restart else do something else I have been looking into trying to see if "logname" exists i.e. "not null" with something like the script below but I don't know how to test for "nullness" or even if that way can ever work. This always returns "somebody logged on" even if no one is. Remember the script runs only on startup so it is quite feasible that it is sitting there with no one logged on. There must be a quick and simple test to see if anyone is logged on, surely! me=$(logname) sleep 30 if [ "$me" = "[ ]" ] # test for "nullness" then echo "no one logged on" >> /Library/management/checkforuser else echo "somebody logged on" >> /Library/management/checkforuser fi |
Check on the return code $?. It's zero if it succeeds and >0 if it fails.
See the man page for logname. |
OK, so you want to trigger software update form the command line?
I think I would approach it this way. Code:
#!/bin/bash |
Tlarkin there will be loads of users because it is a lab. I don't really care about how many or who is currently logged on. I simply want to test if anyone is logged on. I am only using logname because I can't think of another way of how to approach this. My thinking of using it is along the lines of if a variable called logname has something in it, then somebody must be logged on. If it is "null" or empty or doesn't exist, then no one can be logged on. This is probably the the wrong way but it all I can come up with for now.
SirDice, how to I check on a return code ? Something like test -z logname? |
I'd use a 5 minute delay on shutdown and include a system message. Just in case somebody is logged in and the script didn't notice it. That way they get ample warning to save their work.
|
Quote:
Code:
me=`logname` |
Quote:
Quote:
Code:
#!/bin/bash |
Thanks tlarkin
Testing for root seems to work OK, I'll incorporate it in my script. If anyone else is logged on, and a restart is required, then they will get a dialog box asking them to restart, which if they ignore, will send 50 000 volts through to their seat! |
Quote:
< is the BOFH where he works ;) |
a few notes
I am pretty sure now you want to set the environment before the command, so COMMAND_LINE_INSTALL should be set before the softwareupdate command. I also think you may need to drop the word "to" on the display dialog line in the AppleScript. At the time I wasn't near a Mac to test this stuff and didn't have time to look at it until now. My post is too old for me to edit. Please test and post back a working solution. Also, I like the 50k volts idea. That or install ejector seats at every computer, that way you can just eject the user! |
Quote:
When someone else logs in, the console is put into that user's bootstrap namespace, and removed from all other namespaces, including yours. You can no longer see the console, and scripts you run cannot interact with the user. (I.e., they cannot display dialogs.) You'll get an error -10810 if you try. This is a visibility problem, not a permissions problem: even a script running as root can't interact with a console it can't see. If you ssh into the machine as the currently logged in user, your session and the login session both inherit from the user's namespace, and your osascript can find the console and display dialogs, but the dialog doesn't automatically come to the front. You should tell System Events to activate before displaying the dialog, so it won't get buried under the user's windows. (Not that it matters if you can't display the dialog anyway.) Switching to the right user with su isn't enough. You still get error -10810 with the following: Code:
#!/bin/bashCode:
#!/bin/bash |
Gan-
you are right, at the login window that will not display, but if a user is logged in osascript will work. I had not fully tested it yet, but did today while at work over ssh from one iMac to another on my desk. As long as there was a user logged in doing work, it displayed. You had to run the command as root as well. Like I said, not the strongest apple scripter out there, I am still learning. |
OK finally I have got working scripts. I have tested them with a dummy log file which has the words "restart" in its last 4 lines. Now I have to wait for Apple to release an update which requires a restart.
When the machine is started, it runs softwareupdate, the output of which goes into a log file. When the update is finished, the last 4 lines of the log file is "grepped" to see if the word "restart" exists. If so, then the second script is called. This script checks the user, if it is root (nobody logged on) then the machine is restarted. If it is not "root" then an Applescript dialog box with the restart message and two buttons (restart and not now) is called. Here is the first script :- #!/bin/sh sleep 60 COMMAND_LINE_INSTALL=1 export COMMAND_LINE_INSTALL /usr/sbin/softwareupdate -i -a >> /private/var/log/autoupdate.log 2>&1 date >> /var/log/autoupdate.log if tail -n 4 /private/var/log/autoupdate.log | grep -e "restart" then /Library/management/check_user fi Here is the second script :- #!/bin/sh me=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'` if [ $me = "root" ] then shutdown -r now else osascript /Library/management/restart_dialog.app fi I know the above is not very elegant and should be combined into one script but the nested "ifs" together with "&&'s" was beginning to make my head hurt! |
Quote:
If you ssh joe@target.local, then your session can only see things that are in joe's Mach bootstrap namespace. If bill is logged in at the machine, the console (which includes the keyboard and the screen) is in bill's Mach namespace, and you can't see it. More precisely, what you can't see is the WindowServer. This has absolutely nothing to do with users or privilege. Even if you su or sudo to become root, you are still in joe's namespace, and root's vaunted superuser privileges won't let osascript access a device it can't see. |
Quote:
|
I don't have ARD, and know nothing about how it works. Since ARD has to be able to see the screen, I can only presume that when a new user logs in ARD's per-process namespace has its hierarchy changed so that it's now under that user's per-user namespace.
kaptagat is launching the script as a LaunchDaemon. Such a script would run in root's namespace, and would have no access to the WindowServer if a user is logged in. (That's why output from daemons is usually to a logfile.) |
Quote:
thx -T |
I just tested this by logging into my iMac from another Mac, via ssh with a different user account. When I run this:
Code:
sudo osascript -e "tell application "System Events" to display dialog "Hello World!" 'I got the message popped up to me when ran as root. |
That's weird. It doesn't work for me on 10.6.3.
So OK, I played with it some more. Let's suppose that the target machine has two users, Abner and Barney. Abner is an admin, Barney is not. Barney is logged in, and is using the screen. From another machine, I ssh to the target machine as Abner. All commands mentioned below are entered through that ssh session. > osascript -e 'tell application "System Events" to display dialog "Hi"' ... error -10810 ... > sudo osascript -e 'tell application "System Events" to display dialog "Hi"' ... error -10810 ... > osascript -e 'tell application "Finder" to display dialog "Hi"' ... error -10810 ... > sudo osascript -e 'tell application "Finder" to display dialog "Hi"' I hear the target machine beep. I walk over and see Finder's icon bouncing in the dock. I click on the icon, and the dialog comes to the front. I click OK to dismiss it, and back at remote machine I see... button returned:OK That's not the behavior you're reporting, so I decide to explore variations on the theme. Using Fast User Switching on the target machine, I log in also as Abner, and then give control of the screen back to Barney, leaving Abner's session running in the background. Back at the terminal: > osascript -e 'tell application "System Events" to display dialog "Hi"' ... error -10810 ... > sudo osascript -e 'tell application "System Events" to display dialog "Hi"' There's no immediate error, but the dialog doesn't pop up either, even if I hide all of Barney's windows. I use Fast User Switching to go back to Abner's session, and still didn't see a window. I pull up Activity Monitor and see that there is indeed an osascript process running as root. While I'm scratching my head wondering what to try next, the dialog finally pops up out of nowhere. I click OK, and back at the remote machine I see: button returned:OK Switching the target machine back again to Barney, I try the other variants > osascript -e 'tell application "Finder" to display dialog "Hi"' ... error -10810 ... > sudo osascript -e 'tell application "Finder" to display dialog "Hi"' Beep. Finder icon bouncing. I click on bouncing icon to see dialog. Click OK: button returned:OK I never do see the "unable to connect to Window Server" message. Error -10810 is kLSUnknownErr, a catchall error result from Launch Services. The only consistently useful result is with: > sudo osascript -e 'tell application "Finder" to display dialog "Hi"' It always works no matter who is logged in, as long as Finder is running. (If Finder isn't running, we're back to error -10810.) If Finder is not frontmost, it beeps and bounces its icon to get your attention. Telling System Events to display the dialog doesn't always work, and even when it shows the dialog it doesn't bring it to the front. |
This is what I did:
iMac 1 logged in as me, local admin iMac 2 logged in as me, local admin From iMac 2 I ssh'd into iMac 1 with a different account, one that is used for management purposes (also an admin account). If I ran the osascript command with out sudo I got an error, if I ran it with sudo it worked. iMac 1 is 10.5.8 and iMac 2 is 10.6.3. Though, you are probably right on the finder always running, the problem with the finder is that it doesn't bring it to the front like you mentioned. Also, as root if I run the say command it also worked for me. |
So we're probably looking at a difference between 10.5.8 and 10.6.3.
But the advantage of Finder is that it will at least tell you that it has something to say if it's not already in the front. System Events is never in the front (unless your osa script explicitly activates it) and has no dock icon nor any other means to let you know it has a dialog it wants you to see. A dialog from System Events usually gets buried behind all the other user windows. (At least on 10.6. I don't know what it does on 10.5.) Whichever one you tell to display the dialog, you can tell to activate first, so that's not a big deal. What is a big deal is that on 10.6 I can't get another user's System Events to display a dialog even using sudo. It's probably better not to explicitly activate either one. The user we're trying to alert is probably in the middle of something, and won't appreciate having keyboard focus yanked away from him peremptorily. If Finder's not in front, it beeps and bounces its icon, but lets the user finish what he was doing. (Imagine a situation where the user is about to press the return key. If we activate Finder (or System Events) and put up a dialog at that precise moment, the user's keypress will dismiss the dialog they didn't have a chance to read.) Of course, they might not appreciate being kicked off the machine either, but at least they get to finish what they were doing. And isn't that, after all, what we're really after? Letting them finish before the machine restarts? For historical reasons, there's a lot of overlap between Finder and System Events, the primary division of labor being that Finder now focuses on the GUI and foists everything else off onto System Events. Displaying a dialog is definitely GUI, so Finder is the one we should by rights be talking to anyway. Finder's response (beeping and bouncing its icon) is the correct behavior. |
| All times are GMT -5. The time now is 10:38 PM. |
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.