Unicode in shell script defaults

Leading on from Kai’s post (Using Unicode-only characters in script strings), I thought I’d post about this as I couldn’t find it easily elsewhere.

I have found using the unix command defaults very useful in the past to keep a record of strings and numbers safe from one launch of a script to another. Something like:

set enteredText to text returned of (display dialog "Enter characters." default answer "String to save")
-- To enter the text into defaults
do shell script ("defaults write  com.random.domain firstItem " & quoted form of enteredText)

-- To retrieve defaults
set myResult to (do shell script "defaults read com.random.domain firstItem")
display dialog myResult

However I have found that when Unicode text is put through this process it is incorecctly encoded on the way (or way back - I’m not sure which.):

set enteredText to text returned of (display dialog "Enter Unicode characters." default answer («data utxt2661266326622660» as Unicode text))
-- To enter the text into defaults
do shell script ("defaults write  com.random.domain secondItem " & quoted form of enteredText)

-- To retrieve defaults
set myResult to (do shell script "defaults read com.random.domain secondItem")
display dialog myResult

A solution I found for this is to use the unix command xxd to make a hexdump of the data, save this using defaults and then unencode this after retrieving it. (For some reason I couldn’t get uuencode, uudecode to do this.)

set enteredText to text returned of (display dialog "Enter Unicode characters." default answer («data utxt2661266326622660» as Unicode text))
-- To enter the text into defaults
set myHexdump to do shell script "echo " & quoted form of enteredText & " | xxd -p"
do shell script ("defaults write  com.random.domain thirdItem " & quoted form of myHexdump)

-- To retrieve defaults
set myData to (do shell script "defaults read com.random.domain thirdItem")
set myResult to do shell script "echo " & quoted form of myData & " | xxd -r -p"
display dialog myResult

I’d be interested in other ways to deal with this.

Best wishes

John M

The failed middle script returns: “\u2661\u2663\u2662\u2660”. Not very useful, but John’s fix, does indeed work beautifully. Now, if I understood why.

Hi Adam,

I’m with you there, I’ll try and explain some more.

set enteredText to text returned of (display dialog "Enter Unicode characters." default answer («data utxt2661266326622660» as Unicode text))
-- To enter the text into defaults
set myHexdump to do shell script "echo " & quoted form of enteredText & " | xxd -p"
do shell script ("defaults write com.random.domain thirdItem " & quoted form of myHexdump)

The command xxd -p (in the third line) converts the standard input (the result of the echo command before it) into a hexadecimal (base 16) representation of the string. The result of this is passed to the defaults write command. This saves it to a preference file com.random.domain in the user’s preferences folder.

-- To retrieve defaults
set myData to (do shell script "defaults read com.random.domain thirdItem")
set myResult to do shell script "echo " & quoted form of myData & " | xxd -r -p"
display dialog myResult

When the string is needed at a later date you can retrieve it using defaults read. As the string has been encoded (using the xxd command) it needs to be decoded again to return it to the original.

I hope this makes more sense.

John M

FWIW, when looking at the plist file (convert to XML if needed) in other programs “ Property List Editor, BBEdit, and even the UNIX tool “tail” - the data is displayed correctly.

Thanks all for explanations.

Another way to accurately read the plist file is to use System Events’ Property List Suite:

tell application "System Events" to value of property list item "thirdItem" of ¬
	property list file ((path to preferences as Unicode text) & "com.random.domain.plist")

Thanks Kai, that’s much more what I was hoping to do originally.

Best wishes

John M

Lazily not simply trying it, does this work to “set” rather than “get” an item from a property list, i.e. in place of defaults read and defaults write? Will it create the file if it doesn’t exist?

Yes.

No.

Thanks, Bruce. The no means that a proper .plist file has to be set up and saved in advance, and the yes that both reading and writing to it are possible. OK