Skip to main content
Solved

Shell scripting bat signal: defaults not obeying variable resolution


Forum|alt.badge.img+24

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.

Best answer by henkelb

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
View original
Did this topic help you find an answer to your question?

27 replies

Forum|alt.badge.img+3
  • New Contributor
  • 32 replies
  • June 27, 2012

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.


Forum|alt.badge.img+24
  • Author
  • Valued Contributor
  • 1892 replies
  • June 27, 2012

Where, between the <string> and </string> tags? Just tried that and it gave me a dock item of $user`


Forum|alt.badge.img+10
  • Contributor
  • 18 replies
  • June 27, 2012

Have you tried putting $user in quotes like below?

server=dscl . -read /Users/"$user" | grep SMBHome: | cut -d '' -f 3


Forum|alt.badge.img+24
  • Author
  • Valued Contributor
  • 1892 replies
  • June 27, 2012

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.


Forum|alt.badge.img+24
  • Author
  • Valued Contributor
  • 1892 replies
  • June 27, 2012
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.


Forum|alt.badge.img+3
  • New Contributor
  • 32 replies
  • June 27, 2012

Have you tried:

jamf modifyDock -file /Volumes/`echo $user`

J.I.


Forum|alt.badge.img+24
  • Author
  • Valued Contributor
  • 1892 replies
  • June 27, 2012

jamf gives me the

You must specify a an [sic] ID. Type "jamf help modifyDock" for more info

error.


Forum|alt.badge.img+3
  • New Contributor
  • 32 replies
  • June 27, 2012

or even ```
whoami
``` which will return a single string of the current username.

J.I.


Forum|alt.badge.img+31

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.


Forum|alt.badge.img+24
  • Author
  • Valued Contributor
  • 1892 replies
  • June 27, 2012

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.


Forum|alt.badge.img+3
  • New Contributor
  • 32 replies
  • June 27, 2012

Defaults is taking a string passed to it via the shell, it doesn't see the variable at all.

J.I.


Forum|alt.badge.img+24
  • Author
  • Valued Contributor
  • 1892 replies
  • June 27, 2012
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.


Forum|alt.badge.img+24
  • Author
  • Valued Contributor
  • 1892 replies
  • June 27, 2012

I'm going to go crowbar this in with plistbuddy. Maybe I'll have better luck.


mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • 7880 replies
  • June 27, 2012

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.


Forum|alt.badge.img+3
  • New Contributor
  • 32 replies
  • June 27, 2012
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.


Forum|alt.badge.img+5
  • New Contributor
  • 14 replies
  • Answer
  • June 27, 2012

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

Forum|alt.badge.img+18
  • Valued Contributor
  • 1007 replies
  • June 27, 2012

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>");


Forum|alt.badge.img+18
  • Valued Contributor
  • 1007 replies
  • June 27, 2012

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.


mm2270
Forum|alt.badge.img+16
  • Legendary Contributor
  • 7880 replies
  • June 27, 2012

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.


Forum|alt.badge.img+24
  • Author
  • Valued Contributor
  • 1892 replies
  • June 27, 2012

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.


Forum|alt.badge.img+3
  • New Contributor
  • 32 replies
  • June 27, 2012

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.


Forum|alt.badge.img+31
  • Honored Contributor
  • 2721 replies
  • June 27, 2012

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


Forum|alt.badge.img+3
  • New Contributor
  • 32 replies
  • June 27, 2012

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.


Forum|alt.badge.img+13

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.


Forum|alt.badge.img+3
  • New Contributor
  • 32 replies
  • June 27, 2012

Because the same script the original poster made could be accomplished in 2 lines as well. Mounting and creating a Dock icon.

J.I.


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings