dockutil script at login: can't remove all

johnnasset
Contributor

I've been staring at this for too long so I'm reaching out to the pro's for what I bet is a really easy fix. I'm writing a shell script to nuke the dock for specific user accounts (scoped in the JSS) and then making those docks immutable. The first part of this script fails so the rest of the commands can't be completed:

#!/bin/sh

#This script wipes the current lib account dock and rebuilds.  The dock
#is locked using the contents-immutable flag

lab=$echo $3 | head -c 2

/usr/local/bin/dockutil --remove all /Users/$3

/usr/local/bin/dockutil --add /Applications/Firefox.app /Users/$3 --no-restart

/usr/local/bin/dockutil --add '/Applications/Google Chrome.app' /Users/$3 --no-restart

/usr/local/bin/dockutil --add /Applications/Safari.app /Users/$3 --no-restart

/usr/local/bin/dockutil --add '/Applications/Comic Life.app' /Users/$3 --no-restart

/usr/local/bin/dockutil --add '/Applications/Google Earth.app' /Users/$3 --no-restart

/usr/local/bin/dockutil --add '/Applications/GarageBand.app' /Users/$3 --no-restart

/usr/local/bin/dockutil --add '/Applications/iPhoto.app' /Users/$3 --no-restart

/usr/local/bin/dockutil --add '/Applications/Microsoft Office 2011/Microsoft Word.app' /Users/$3 --no-restart

/usr/local/bin/dockutil --add '/Applications/Microsoft Office 2011/Microsoft Excel.app' /Users/$3 --no-restart

/usr/local/bin/dockutil --add '/Applications/Microsoft Office 2011/Microsoft PowerPoint.app' /Users/$3 --no-restart

/usr/local/bin/dockutil --add /Applications/SBACSecureBrowser6.3.app /Users/$3 --no-restart

/usr/local/bin/dockutil --add 'smb://xxx/labarea/$lab/Labarea --view grid --display folder /Users/$3 --no-restart

/usr/local/bin/dockutil --add 'http:/xxx.org/lms/sm.view?headless=1&action=home' --label 'SuccessMaker' /Users/$3 --no-restart

/usr/local/bin/dockutil --add 'https://xxx.follettdestiny.com' --label 'Library Catalog' /Users/$3 --no-restart

/usr/local/bin/dockutil --add 'https://xxx.renlearn.com/xxx/default.aspx' --label 'AR/STAR' /Users/$3 --no-restart

defaults write /Users/$3/Library/Preferences/com.apple.dock contents-immutable -boolean TRUE

defaults write /Users/$3/Library/Preferences/com.apple.dock size-immutable -boolean TRUE

defaults write /Users/$3/Library/Preferences/com.apple.dock position-immutable -boolean TRUE

defaults write /Users/$3/Library/Preferences/com.apple.dock magnify-immutable -boolean TRUE

defaults write /Users/$3/Library/Preferences/com.apple.dock autohide-immutable -boolean TRUE

killall Dock

The accounts we are targeting are AD accounts but the $3 variable is getting the correct account name so I don't think that's the issue. Any assistance is appreciated.

16 REPLIES 16

davidacland
Honored Contributor II

Not sure if dockutil handles it directly but you might need to add:

killall cfprefsd

at the start of the script to make sure the preference isn't cached.

dmw3
Contributor III

There is a syntax error at - /usr/local/bin/dockutil --add /Applications/SBACSecureBrowser6.3.app /Users/$3 --no-restart

Although that should not halt the script.

mm2270
Legendary Contributor III

There isn't anything wrong with this line as far as I can see:

/usr/local/bin/dockutil --add /Applications/SBACSecureBrowser6.3.app /Users/$3 --no-restart

But there is with the line after:

/usr/local/bin/dockutil --add 'smb://xxx/labarea/$lab/Labarea --view grid --display folder /Users/$3 --no-restart

It doesn't have a closing single quote at the end of the URL.

I'm not sure if that's just a typo when you pasted it here or if its actually like that.
Because of how scripts can get evaluated, that single missing quote could actually cause the script to fail to run at all, meaning it may be stopping it from getting to the first step. If that's how its actually written, fix that first and try it again.

Also, what version of dockutil are you using for this? Kyle used to include the killall cfprefsd automatically at the end, but in version 2.0 and later it was removed. I'm not sure why since my experience seems to be that its still almost always necessary with these kinds of things. I haven't tested version 1.1.4 against Yosemite yet, but it may still work on that version. Even so, that probably isn't what's tripping this up.

Also, have you considered setting up a one time LaunchAgent and having that run the script so you don't need to have it run as root but affecting the logged in user's Dock?

johnnasset
Contributor

Of course the missing single quote was causing the script to fail. Stare at something long enough.....

Now the existing dock gets dumped but none of the new items get repopuated. From the JSS log:

Executing Policy Elementary Dock Maintenance...
Creating directory structure for /Library/Application Support/JAMF/Downloads/
Downloading https://xxx.org/CasperShare/Scripts/elemdock.sh...
Running script elemdock.sh...
Script exit code: 0
Script result: --no-restart does not seem to be a home directory or a dock plist
--no-restart does not seem to be a home directory or a dock plist
Safari already exists in dock. Use --replacing 'Safari' to update an existing item
item /Applications/Safari.app was not added to Dock
--no-restart does not seem to be a home directory or a dock plist
--no-restart does not seem to be a home directory or a dock plist
--no-restart does not seem to be a home directory or a dock plist
iPhoto already exists in dock. Use --replacing 'iPhoto' to update an existing item
item /Applications/iPhoto.app was not added to Dock
--no-restart does not seem to be a home directory or a dock plist
--no-restart does not seem to be a home directory or a dock plist
--no-restart does not seem to be a home directory or a dock plist
--no-restart does not seem to be a home directory or a dock plist
--no-restart does not seem to be a home directory or a dock plist
--no-restart does not seem to be a home directory or a dock plist

@mm2270 I've never setup a launch agent. What are the specific advantages vs the $3 variable?

mm2270
Legendary Contributor III

Hmm. Based on the "--no-restart does not seem to be a home directory" error, I'd say its not recognizing either $3, or it is but is thinking the --no-restart is part of the user home dir path.

For good measure, I'd wrap everything in single quotes, including the '/Users/$3' and any other paths to items you're trying to add in to prevent any misreading of them by dockutil.

As for the LaunchAgent, my standard response here is if you decided to try it, I would use LaunchControl, or the older Lingon. These apps make sure all permissions and ownership are set up correctly on them, so it takes a lot of the sometimes frustrating guesswork out of it.
A launchAgent runs as the logged in user, so there would be no need to even include a path to the users home directory in your script, since in its default mode, dockutil assumes its working on the logged in user's Dock items.
At the end of the script, simply include a line that deletes the LaunchAgent. This would only work in the case of a User LaunchAgent, as in one that's in ~/Library/LaunchAgents/. Anything in /Library/LaunchAgents/ (global user LaunchAgents) can only be deleted with admin rights or by root.
But first off, try enclosing your path to the user home in single quotes and see if that helps stop those errors.

mm2270
Legendary Contributor III

Ah, I just realized what the problem is, I think.
You need to include the path to the users home folder at the very end of each line. All the flags for dockutil will go before it. In other words try it like this:

/usr/local/bin/dockutil --add '/Applications/Firefox.app' --no-restart /Users/$3

I just tried something like that on my Mac using dockutil 1.1.4 and it worked. Well, I also needed to do killall cfprefsd and killall Dock but the icon appeared afterwards. Change the lines to look like above and try that way.

cbrewer
Valued Contributor II

I've found some dockutil commands are only successful when run as the user. Specifically this has been an issue running 2.0.2 on Yosemite.

su -l $3 -c "/usr/local/bin/dockutil --add '/Applications/Firefox.app' --no-restart"

johnnasset
Contributor

Even though I have "Perform login hook actions in background" unchecked, my user variable keeps picking up root as the current user. Here is the user variable:

user=$(ls -la /dev/console | cut -d " " -f 4)

Error in the JSS:

/var/root/Library/Preferences/com.apple.dock.plist does not seem to be a home directory or a dock plist

The entire login script:

#!/bin/sh

#This script wipes the current lib account dock and rebuilds.  The dock
#is locked using the contents-immutable flag

user=$(ls -la /dev/console | cut -d " " -f 4)
plist=$('/Users/$user/Library/Preferences/com.apple.dock.plist')
lab=$(echo $user | head -c 2)


/usr/local/bin/dockutil --remove all $plist

/usr/local/bin/dockutil --add '/Applications/Firefox.app'  --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Google Chrome.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Safari.app'  --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Comic Life.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Google Earth.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/GarageBand.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/iPhoto.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Microsoft Office 2011/Microsoft Word.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Microsoft Office 2011/Microsoft Excel.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Microsoft Office 2011/Microsoft PowerPoint.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/SBACSecureBrowser6.3.app' --no-restart $plist 

/usr/local/bin/dockutil --add 'smb://xxx/labarea/$lab/Labarea' --view grid --display folder --no-restart $plist

/usr/local/bin/dockutil --add 'http://xxx.org/lms/sm.view?headless=1&action=home' --label 'SuccessMaker' --no-restart $plist

/usr/local/bin/dockutil --add 'https://xxx.com' --label 'Library Catalog' --no-restart $plist

/usr/local/bin/dockutil --add 'https://xxx.renlearn.com/111/default.aspx' --label 'AR/STAR' $plist

defaults write $plist contents-immutable -boolean TRUE

defaults write $plist size-immutable -boolean TRUE

defaults write $plist position-immutable -boolean TRUE

defaults write $plsit magnify-immutable -boolean TRUE

defaults write $plist autohide-immutable -boolean TRUE

killall cfprefsd

killall Dock

mm2270
Legendary Contributor III

There's another thread on a similar problem someone else is encountering now with login policies. It should be picking up the just logged in user name, so I don't quite understand what the issue is there. We don't use any login policies, so I can't really test this out just yet.

This goes back to my mentioning the LaunchAgent to call the script. Its a bit harder to manage than just having a policy in the JSS take care of this though, so I understand if you don't want to go that route.

How about this? Add a significant pause to the beginning of the script, before it captures the logged in user name? Something like 5-10 seconds sleep, then get the logged in user and then run the rest of the commands.
My guess is somehow now these login hook scripts are running a little premature and getting root because that would be the owner of the console (login window) when it fires off.

pat_best
Contributor III

just to add my two cents... we have had better success with a "remove all then add items" approach by adding a 5 second sleep between the remove and add commands

johnnasset
Contributor

This is just strange. I can't get the current user to populate in the script correctly. I dropped the script on the client and tried to run locally and still can get the current user variable to populate. Deconstructing even further, I just tried running

dockutil --remove all

I get the following error in Terminal:

Command line interface to a user's defaults.
Syntax:

'defaults' [-currentHost | -host <hostname>] followed by one of the following:

  read                                 shows all defaults
  read <domain>                        shows defaults for given domain
  read <domain> <key>                  shows defaults for given domain, key

  read-type <domain> <key>             shows the type for the given domain, key

  write <domain> <domain_rep>          writes domain (overwrites existing)
  write <domain> <key> <value>         writes key for domain

  rename <domain> <old_key> <new_key>  renames old_key to new_key

  delete <domain>                      deletes domain
  delete <domain> <key>                deletes key in domain

  domains                              lists all domains
  find <word>                          lists all entries containing word
  help                                 print this help

<domain> is ( <domain_name> | -app <application_name> | -globalDomain )
         or a path to a file omitting the '.plist' extension

<value> is one of:
  <value_rep>
  -string <string_value>
  -data <hex_digits>
  -int[eger] <integer_value>
  -float  <floating-point_value>
  -bool[ean] (true | false | yes | no)
  -date <date_rep>
  -array <value1> <value2> ...
  -array-add <value1> <value2> ...
  -dict <key1> <value1> <key2> <value2> ...
  -dict-add <key1> <value1> ...

Same error with dockutil --remove 'Safari'

Tested on a 10.8.5, 10.9.x and 10.10.x machine using dockutil 2.0.2.

mm2270
Legendary Contributor III

@johnnasset - are you strictly using version 2.0.2?
This is going to sound like a strange suggestion, but can you test your script or commands after downloading version 1.1.4? Yes, I know that's not listed as being compatible with Yosemite, but just try it.

mm2270
Legendary Contributor III

Hey @johnnasset - a couple other things. I didn't even notice it before, but in the script you posted on 12/10, I see that you have the path to the current user's plist enclosed as if its running a command, meaning you've enclosed it with $(...) I'm not sure why, since that shouldn't be needed. its just a string/path, so just write it like this instead:

plist="/Users/$user/Library/Preferences/com.apple.dock.plist"

I'm not sure if that's the reason its not getting the current user's Dock.plist path or not. Its hard to know, but I do know what you had there before won't really work to locate the user's plist.

That could explain why its saying its trying to use root's plist. Since the $plist variable is probably not being populated at all in that script, it's assuming it needs to operate on the root account's Dock.plist, which is what's running the script.

johnnasset
Contributor

Awesome @mm2270, started doing what I intended when I dropped dockutil down to 1.1.4. One last thing, the $lab variable doesn't seem to work:

lab=$(echo $user | head -c 2)

/usr/local/bin/dockutil --add 'smb://files/labarea/$lab/Labarea' --label 'Labarea' --view grid --display folder --no-restart $plist

The $lab variable should be the first two letters of the logon name (smlib is sm, etc). Any ideas?

Really appreciate your help on this Mike.

mm2270
Legendary Contributor III

@johnnasset,
Try using the shell's built in variable expansion instead:

lab=${user:0:2}

You could also use cut if you really wanted to, like:

lab=$(echo $user | cut -c -2)

but the first example above should work.

johnnasset
Contributor

Thanks for all of the help. I modified the way the file share is put into the dock so as to avoid presentation as a web clip. This script runs great when a user is logged in but will not properly run when logging in. Can't seem to populate the current user no matter how much of a sleep delay I use. Here is the "final" version of the script:

#!/bin/sh

#This script wipes the current lib account dock and rebuilds.  The dock
#is locked using the contents-immutable flag

sleep 15

user=$(python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");')
plist="/Users/$user/Library/Preferences/com.apple.dock.plist"
lab=$(echo $user | cut -c -2)


/usr/local/bin/dockutil --remove all --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Firefox.app'  --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Google Chrome.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Safari.app'  --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Comic Life.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Google Earth.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/GarageBand.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/iPhoto.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Microsoft Office 2011/Microsoft Word.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Microsoft Office 2011/Microsoft Excel.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/Microsoft Office 2011/Microsoft PowerPoint.app' --no-restart $plist

/usr/local/bin/dockutil --add '/Applications/SBACSecureBrowser6.3.app' --no-restart $plist 

jamf mount -server files/LabArea/$lab -share Labarea -type smb -username $user -password student -visible

/usr/local/bin/dockutil --add '/Volumes/Labarea' --label 'Labarea' --no-restart $plist

/usr/local/bin/dockutil --add 'http://xxx.org/lms/sm.view?headless=1&action=home' --label 'SuccessMaker' --no-restart $plist

/usr/local/bin/dockutil --add 'https://xxx.com' --label 'Library Catalog' --no-restart $plist

/usr/local/bin/dockutil --add 'https://xxx.renlearn.com/999/default.aspx' --label 'AR/STAR' $plist

defaults write $plist contents-immutable -boolean TRUE

defaults write $plist size-immutable -boolean TRUE

defaults write $plist position-immutable -boolean TRUE

defaults write $plsit magnify-immutable -boolean TRUE

defaults write $plist autohide-immutable -boolean TRUE

killall cfprefsd

killall Dock