There isn't an easy way to run the entire script as the user, unless you deployed it as a local script and called it via a LaunchAgent, but you can run portions of the script as the logged in user, or, in your case, simply determine who the logged in user is and make sure to direct the command at their files and preferences.
So using what you have above, the following should work to ensure the logged in user's plist is being written to.
#!/bin/bash
loggedInUser=$(stat -f%Su /dev/console)
mkdir -p /Users/$loggedInUser/New_SCREEN_SHOTS_Folder
/usr/bin/defaults write /Users/$loggedInUser/Library/Preferences/com.apple.screencapture.plist location /Users/$loggedInUser/New_SCREEN_SHOTS_Folder
## Make sure the plist we just wrote to as root is owned by the user and not root
/usr/sbin/chown $loggedInUser /Users/$loggedInUser/Library/Preferences/com.apple.screencapture.plist
killall SystemUIServer
EDIT: Looking at it again, you may also want to throw in an extra chown -R
command against the new folder the script creates, just to ensure the user also owns that directory and not root.
If running via Self Service, $3 works to get the username.
No idea why I didn't do it, here but seems a similar script.
@bentoms @mm2270 Thanks for you guidance. I remembered that $3 outputs the current user logged in. So, do you think adding an "su -c $3" line at the beginning should work?
#!/bin/bash
su -c $3
mkdir -p $HOME/New_SCREEN_SHOTS_Folder
defaults write com.apple.screencapture location $HOME/New_SCREEN_SHOTS_Folder
killall SystemUIServer
exit 0
Otherwise, more like your suggestions:
#!/bin/bash
mkdir -p $HOME/New_SCREEN_SHOTS_Folder
defaults write $HOME/Library/Preferences/com.apple.screencapture location $HOME/New_SCREEN_SHOTS_Folder
chown $3 /Users/$HOME/Library/Preferences/com.apple.screencapture.plist
chown -R $3 /Users/$HOME/New_SCREEN_SHOTS_Folder
killall SystemUIServer
exit 0
I know you both defined the home folder path more specifically as "/Users/$loggedInUser/folderpath," but $HOME does the same, correct? Do you think I would also have to include a couple of "chmod" lines for the plist and folder being created?
I'm just trying to use as few lines as possible.
You can use launchctl
to run commands using the logged-in user's privileges. I discuss how to do that as part of the post linked below:
https://derflounder.wordpress.com/2016/03/25/running-processes-in-os-x-as-the-logged-in-user-from-outside-the-users-account/
For a practical example of how I've used it, please see the link below:
[https://derflounder.wordpress.com/2016/11/10/providing-website-links-via-casper-self-service-policies/](lhttps://derflounder.wordpress.com/2016/11/10/providing-website-links-via-casper-self-service-policies/)
I don't believe the $HOME variable will work in a case of the script being run by another account, like the service account or root. For example, if you simply switch to another account on the Mac in Terminal, like su administrator
and then run echo $HOME
you'll see the path it prints is of the account you just logged into, not your home path. Because it doesn't work in that context, you would need to use something like /Users/$3/
or /Users/$loggedInUser/
, meaning the full path to the home directory.
As for whether to use $3 or a separate logged in user variable, that is entirely up to you. $3 certainly works for your case scenario, but I tend to write scripts to be as portable as possible (at least most times). I never know if I'll end up running the script in a different context, like not from Self Service. In that case, a separate variable that would always get the logged in user would work in those extras cases, not just from Self Service or the login/logout trigger. But its really up to you. If you're pretty confident you'll only be running this from Self Service, then $3 should be fine to use.
Are the users always going to run it from Self Service?
I've had to run package installers before as the user and ended putting the package within a package using Composer to copy the file locally then ran a script using the su command to run the pkg as the user. This was all being done silently/in the background using a checkin as a trigger (vs. initiation from Self Service). I noticed differences in launching via Self Service and launching via recurring checkin when using sudo vs. su -c, just a heads up. That was mostly related to running the pkg installation, though.
Snippet:
current_user=$( ls -la /dev/console | cut -d " " -f 4 )
su -l $current_user -c "/usr/sbin/installer -verboseR -dumplog -pkg /path/to/packag/installer.pgk -target CurrentUserHomeDirectory"
I don't think your use case would warrant copying a separate script down, just run the commands requiring user privileges with su. Sudo -u $current_user can also work as a prefix to the command you're trying to run but like I said, I saw odd behaviors with that so just something to keep in mind. Hope this helps.
**@mm2270 "There isn't an easy way to run the entire script as the user, unless you deployed it as a local script and called it via a LaunchAgent"
Could you please elaborate on that or maybe some step-by-step guide? I have a script that has to be run completely by the user and your way seems to be the only one.
Thanks