Plist items with special characters [Shell quoting/escaping]

set testname to "System Preferences"
set testpreference to "1"

(do shell script "defaults write MyPreference " & testname & " " & testpreference)
(do shell script "defaults read MyPreference " & testname)

I’m trying to read/save plist. I use standard defaults read command but if testname contains
space
.

_

then it fails. If testname is “SystemPreferences” then if works, but if its “System Preferences” then it fails.

You probably need to quote the value before passing it to the shell (the problem is not with plists).

set testname to "System Preferences"
set testpreference to "1"

(do shell script "defaults write MyPreference " & quoted form of testname & " " & quoted form of testpreference)
(do shell script "defaults read MyPreference " & quoted form of testname)

FYI, I use something like this:

script userDefaults
	property _domain : quoted form of "DefaultDomain"
	
	on readKey(_key, _defaultValue)
		try
			do shell script "/usr/bin/defaults read " & _domain & space & quoted form of _key
		on error
			return _defaultValue
		end try
	end readKey
	
	on writeKey(_key, _value)
		do shell script "/usr/bin/defaults write " & _domain & space & quoted form of _key & space & quoted form of _value
	end writeKey
end script

-- Example
repeat
	tell userDefaults to readKey("Test", "Default value")
	display dialog ("Current value: " & result) default answer ""
	tell userDefaults to writeKey("Test", text returned of result)
end repeat

I love your script, thanks.

What is best way to read all these setting in one command preferrably without loops? I tried “every paragraph of” but that dont put key and value to own item in list.

I saved few test preferences to plist:

Test First = 1
Test Second = 2
Test Third = 3

What is best way to read these all once?

Bruce;

Very nice script, but for us dummies, is DefaultDomain in the script object meant to be the posix path to ~/Library/Preferences/ or can it be any posix path?

If you don’t use a whole path, it uses ~/Library/Preferences/; However, you can also supply a valid POSIX path to somewhere else.

Edit: cirno, why not use something like this?

tell userDefaults
	set testFirst to readKey("Test First", "")
	set testSecond to readKey("Test Second", "")
	set testThird to readKey("Test Third", "")
end tell

Those 3 was just an example. Unfortunately i have maybe few hundred of preferences to save so this is not practical. I have tried alot of thins but it always fails. I need something like “read all preferences in plist”. Thanks

The most reliable way would be to parse the XML file yourself.

Hi cirno,

you can use the built in property list commands of System Events
here a simple example

set pListpath to (path to preferences as string) & "xxx.yyyyy.zzzz.plist"
set {Lname, Lvalue} to {{}, {}}
tell application "System Events"
	tell property list file pListpath
		repeat with i in property list items of contents
			copy {name of i, value of i} to {end of Lname, end of Lvalue}
		end repeat
	end tell
end tell

Thanks for posting that, Stefan. :cool:

Remember, though, that copy can be less efficient (because it actually copies a value, using that much more memory) than set; You should only use it when you need to avoid data sharing.

Hi Bruce,

well, I know that, the reason for that syntax is,
I wrote the arguments in the wrong order and was too lazy to swap them,
so I used copy :wink:
Sorry :smiley:

I recently found this Tool to write and read settings in a tiffy.
works fine for me.

http://www.latenightsw.com/freeware/PListTools/index.html

Browser: Firefox 2.0.0.1
Operating System: Mac OS X (10.4)