Screen saver script run as current user

Bongardino
New Contributor III

Having trouble getting a script to run as the logged in user instead of root. I've searched here pretty thoroughly but can't find a working solution.

The script checks the screen saver idle time of the logged in user; if less than 10 minutes it does nothing. If more than 10, it sets it to 10.

It works fine when run as the user but I can't get it to work when run by root / casper.

Here's what I've got so far. I've had luck using this $currentuser string with extension attributes but no luck here.

#!/bin/bash
# Max idle time for the screensaver in seconds.

idleMax=600
idleTime=$(/usr/bin/defaults -currentHost read com.apple.screensaver idleTime 2> /dev/null)

currentuser=$(stat -f '%Su' /dev/console | /usr/bin/cut -d ' ' -f 4)


if [ $? -eq 1 ]; then

  defaults -currentHost write com.apple.screensaver idleTime -int ${idleMax}


elif [[ ${idleTime} -gt ${idleMax} || ${idleTime} -eq 0 ]]; then

  sudo -ui $currentuser defaults -currentHost write com.apple.screensaver idleTime -int ${idleMax}
  echo "screensaver time outside of scope; changed to 10 minutes"

fi
7 REPLIES 7

bentoms
Release Candidate Programs Tester

@Bongardino Yout might need to be more explicit with the paths for the defaults commands as some will run under root, others the user.

I've got an old post here that might help, someone said that it works for them on 10.11.x/10.12.x i'd not use plistbuddy for this now.

russeller
Contributor III

@Bongardino I've used this while running a script as root that needs to modify a user preference:

su -l $currentuser -c

so something like this:
su -l $currentuser -c "defaults -currentHost write com.apple.screensaver idleTime -int ${idleMax}"

Here is what the man page for su says about the -l switch

     -l      Simulate a full login.  The environment is discarded except for
             HOME, SHELL, PATH, TERM, and USER.  HOME and SHELL are modified
             as above.  USER is set to the target login.  PATH is set to
             ``/bin:/usr/bin''.  TERM is imported from your current environ-
             ment.  The invoked shell is the target login's, and su will
             change directory to the target login's home directory.

thoule
Valued Contributor II

I found it much easier to create a launchAgent to run my script. Then it's applied to the user on each login.

Bongardino
New Contributor III

@thoule I was originally trying to do it that way but got stuck and I'm not sure where I'm failing.

I've verified the launch agent is loaded, built it through lingon, placed it in ~/Library/LaunchAgents/
The script lives in ~/Library/ApplicationSupport/com.myorganization.org/
The script it calls is the same as the one posted above, without the currentuser variable.

Any idea what I've missed? I installed it via PKG I built in composer. Do I need to chmod it after installation or something?

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/Server.app/Contents/ServerRoot/usr/bin:/Applications/Server.app/Contents/ServerRoot/usr/sbin:(B:/usr/local/sbin</string>
    </dict>
    <key>Label</key>
    <string>org.betterment.screensaverlock.plist</string>
    <key>ProgramArguments</key>
    <array>
        <string>~/Library/Application Support/com.betterment.org/screensaverpolicy.sh</string>
    </array>
    <key>StartCalendarInterval</key>
    <array>
        <dict>
            <key>Hour</key>
            <integer>2</integer>
            <key>Minute</key>
            <integer>1</integer>
        </dict>
    </array>
</dict>
</plist>

Bongardino
New Contributor III

@ssrussell Gave that a shot, no dice!
@bentoms I actually found your script / site when searching. It was helpful as it made me realize what I should be running as the user vs root

thoule
Valued Contributor II

https://github.com/tmhoule/ScreenSaverManagement

My old screensaver management scripts are at that URL. You are welcome to start there and then modify them. As for yours, I've never used ~ in the path name in a LaunchAgent before.. Also, I see you have StartCalendarInterval. Are you sure that's how you wanted it? Not just at login or something?

russeller
Contributor III

@Bongardino When it comes to LaunchAgents it usually comes down to permissions that cause issues. I've also found that the ~ doesn't expand correctly to a home path in a LaunchAgent, but maybe that works now. If you wanted to continue to pursue the LaunchAgent I'd move the script to a centrally accessible area like /Library/Application Support/betterment/scripts/screensaverpolicy.sh and make sure its readable by standard users. Then make sure you set the permissions on the LaunchAgent to:

chmod 644 /Users/username/Library/LaunchAgents/org.betterment.screensaverlock.plist

Then try again. If it continues not to work you can run (as the user) launchctl list | grep betterment to see if it is loaded or if it is loaded with an error.



Also the above suggestion of running a Casper Policy with su -l $currentuser -c "defaults -currentHost write com.apple.screensaver idleTime -int ${idleMax}" worked for me when I removed -currentHost and replaced it with the users home path (like @bentoms suggested) so something like /Users/$currentuser/Library/Preferences/com.apple.screensaver Give that a shot if you wanted to pursue that login policy method.

The entire script would be something like:

#!/bin/bash
# Max idle time for the screensaver in seconds.
idleMax=600
currentuser=$(stat -f '%Su' /dev/console | /usr/bin/cut -d ' ' -f 4)
idleTime=$(su -l $currentuser -c "defaults read /Users/$currentuser/Library/Preferences/com.apple.screensaver idleTime" 2> /dev/null)

if [[ ${idleTime} -gt ${idleMax} || ${idleTime} -eq 0 ]]; then
  su -l $currentuser -c "defaults write /Users/$currentuser/Library/Preferences/com.apple.screensaver idleTime -int ${idleMax}"
  echo "screensaver time outside of scope; changed to 10 minutes"
else
  echo "screensaver time set correctly"
fi