Posted on 06-27-2012 09:38 AM
Okay, this may sound a bit odd given my shell scripting experience, but I need help. It's probably something stupid. Here's the script I've got:
#!/bin/ksh
# Filename: mountShares.sh
# Purpose: Mount file shares automatically with Kerberos ticket
# Author: Jared F. Nichols
user=`ls -la /dev/console | cut -d " " -f 4`
server=`dscl . -read /Users/$user | grep SMBHome: | cut -d '' -f 3`
jamf mount -server $server -share $user -type smb
defaults write com.apple.dock persistent-others -array-add '<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/Volumes/$user</string><key>_CFURLStringType</key><integer>0</integer></dict><key>showas</key><integer>2</integer></dict><key>tile-type</key><string>directory-tile</string></dict>'
killall Dock
The gist is that it will take a kerberos ticket, mount a server share and then put the share in the dock. My issue is that for the life of me I can't get $user to resolve. Defaults puts a literal "$user" in on the dock. I've tried all manner of escaping it, quoting, setting the defaults as another variable (which can get it to resolve properly) and then, essentially, run the variable - all to no effect.
Any ideas?? I should be able to lick this one but it's kicking my arse.
Solved! Go to Solution.
Posted on 06-27-2012 10:27 AM
This also seems to work.
tmpStr='<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/Volumes/'$user'</string><key>_CFURLStringType</key><integer>0</integer></dict><key>showas</key><integer>2</integer></dict><key>tile-type</key><string>directory-tile</string></dict>'
defaults write com.apple.dock persistent-others -array-add $tmpStr
Posted on 06-27-2012 09:45 AM
Have you tried this?
`echo /Volumes/$user`
To give you:
<string>`echo /Volumes/$user`</string>
When you do defaults write com.apple.dock persistent-others -array-add, you are passing it a string so it will read $user as a string. You use tics to escape out of the string to execute a command which will be substituted in the string.
J.I.
Posted on 06-27-2012 09:48 AM
Where, between the <string> and </string> tags? Just tried that and it gave me a dock item of $user`
Posted on 06-27-2012 09:50 AM
Have you tried putting $user in quotes like below?
server=dscl . -read /Users/"$user" | grep SMBHome: | cut -d '' -f 3
Posted on 06-27-2012 09:50 AM
Consequently, I've also tried using ```
jamf modifyDock -file /Volumes/$user
```
But it returns an error that I need to specify an ID. Seems like a bug in the modifyDock verb as the help for it seems to indicate that you can use either -file or -id, not that it requires both.
Posted on 06-27-2012 09:53 AM
Have you tried putting $user in quotes like below?
server=dscl . -read /Users/"$user" | grep SMBHome: | cut -d '' -f 3
Didn't change anything. The issue seems to be how to escape the variable out so that Defaults isn't processing it literally.
Posted on 06-27-2012 09:54 AM
Have you tried:
jamf modifyDock -file /Volumes/`echo $user`
J.I.
Posted on 06-27-2012 09:56 AM
jamf gives me the
You must specify a an [sic] ID. Type "jamf help modifyDock" for more info
error.
Posted on 06-27-2012 09:56 AM
or even ```whoami
``` which will return a single string of the current username.
J.I.
Posted on 06-27-2012 09:59 AM
Can you substitute $USER in place of your existing $user? $USER should give you the current logged-in user without needing to define it otherwise.
Posted on 06-27-2012 10:01 AM
Good idea, but dock item of
`whoami`
There's got to be something about Defaults that processes everything literally. It's sort of obnoxious at this point. ha
Nothing in the man page about it. Wonder if I should try plistbuddy instead.
Posted on 06-27-2012 10:03 AM
Defaults is taking a string passed to it via the shell, it doesn't see the variable at all.
J.I.
Posted on 06-27-2012 10:03 AM
Can you substitute $USER in place of your existing $user? $USER should give you the current logged-in user without needing to define it otherwise.
Result: $USER dock item. It's almost comical at this point.
Posted on 06-27-2012 10:06 AM
I'm going to go crowbar this in with plistbuddy. Maybe I'll have better luck.
Posted on 06-27-2012 10:11 AM
Yeah, seems to me defaults can't use a variable in that kind of command for whatever reason. I guess its just a limitation of the program.
Try PlistBuddy as you state or look at 3rd party tools. You should be able to do this with existing tools though, so its pretty strange.
Posted on 06-27-2012 10:22 AM
R0190381:~ jamieivanov$ defaults write com.apple.dock persistent-others -array-add "<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>`echo /Users/$USER`</string><key>_CFURLStringType</key><integer>0</integer></dict><key>showas</key><integer>2</integer></dict><key>tile-type</key><string>directory-tile</string></dict>"
R0190381:~ jamieivanov$ killall -9 Dock
That placed an icon on the Dock to the appropriate path. It worked just fine for me. Like I said, defaults only reads a string and using ticks (the tilde key to the left of the "1" key), not single quotes.
J.I.
Posted on 06-27-2012 10:27 AM
This also seems to work.
tmpStr='<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>/Volumes/'$user'</string><key>_CFURLStringType</key><integer>0</integer></dict><key>showas</key><integer>2</integer></dict><key>tile-type</key><string>directory-tile</string></dict>'
defaults write com.apple.dock persistent-others -array-add $tmpStr
Posted on 06-27-2012 10:27 AM
when you put things inside of a 'single quote' they don't expand
what i would suggest is trying to wrap that argument in " to see if that works, but i fear the <> will get interpreted at that point.
we do something very similar in perl like this:
system("defaults", "write", "$target", "persistent-apps", "-array-add", "<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>$app_path</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>");
Posted on 06-27-2012 10:42 AM
nice Bill, i was just going to test something like, that because it was gnawing at my brain how to set a tmp string in shell and pass it. i was worried that you would need single quotes in the command and then not get anything close to what you wanted to get.
Posted on 06-27-2012 10:46 AM
Looks like Jamie is spot on. Enclose it in double quotes, not single and it seems to work. In fact, I didn't need to do the echo portion. Something like the below works as is:
defaults write com.apple.dock persistent-others -array-add "<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>**/Users/$user/**</string><key>_CFURLStringType</key><integer>0</integer></dict><key>showas</key><integer>2</integer></dict><key>tile-type</key><string>directory-tile</string></dict>"
It adds my home folder to the Dock. I'm guessing the same would be true if doing /Volumes/$user/ instead.
Posted on 06-27-2012 10:47 AM
Bill gets a cookie - or beverage of his choice should we run into eachother at the NUC.
Holy ba-jeebus I don't know why that was so hard.
jamie
For some reason the backticks (a.k.a grave) aren't working for my on this system (10.7.4). I get what they do but for some reason defaults for me was totally ignoring that.
Posted on 06-27-2012 10:53 AM
It wasn't so hard. Also, I'm running 10.7.4 and using bash just like everyone else. The shells are the same unless there is a problem with encoding/localizations or a keyboard malfunction. It's mere shell scripting.
Though what was difficult was the harder-than-it-needs-to-be solutions.
J.I.
Posted on 06-27-2012 10:54 AM
I think Bill is on the right path here. It is like trying to pass a bash variable in a bash script, apple script, or say into an awk program. The output doesn't carry over since they are separate sets of binaries.
So, you can echo out the results, like so:
echo "a bunch of xml settings" > com.apple.somepropertlylist
or
setttings="<xml stuff that makes you go cross eyed>"
defaults write com.someplist $settings
or
echo $settings > com.someplist
I haven't tested any of these methods but I have used very similar things using bash to apple script, apple script to bash, and bash to awk.
I will try to test some of these this weekend - only if time permits.
Thanks,
Tom
Posted on 06-27-2012 10:55 AM
A little complicated much? Also, don't forget to add some newline strings to make it a little easier to read if you had to manually manipulate the plist. But don't over-engineer, that's when more problems get introduced. Keep it simple, efficient, and functional. There is no need to re-invent the wheel if it already exists.
J.I.
Posted on 06-27-2012 11:22 AM
why don't you use mcx for this and skip all the fragile code?
doesn't this do about the same thing except for mounting?
com.apple.dock
MCXDockSpecialFolders-Raw
<array>
<string>AddDockMCXOriginalNetworkHomeFolder</string>
</array>
there should be a key for com.apple.loginwindow that mounts the share automatically, too.
Posted on 06-27-2012 11:24 AM
Because the same script the original poster made could be accomplished in 2 lines as well. Mounting and creating a Dock icon.
J.I.
Posted on 06-27-2012 11:24 AM
My first thought was MCX as well, but I didn't have time to test it out. I do vaguely remember something in WGM that allowed you to do this, I think. Been a while since I had to use OD to Manage Macs so I am starting to forget some of it.
-Tom
Posted on 06-27-2012 11:48 AM
I originally tried MCX to plant the volume there, but due to every login essentially being an offline login with FV2, it didn't quite work the way I expected and you'd get an error that the system couldn't connect to the server. The script was really just an easy way for techs to setup a "drive map." More a stop-gap solution than anything else.