defaults read multiple times with one shell script call?

Typically if I need to pull the info out of a plist file, I’ll run a shell script command for each variable I need to get info from:

set foo to (do shell script "defaults read com.My.Script 'firstVariableToRead' ")
set bar to (do shell script "defaults read com.My.Script 'secondVariableToRead' ")
--etc...

I know doing a shell script command takes some time, and I’m wondering if I’m compounding that time by requesting a new shell script for each item I want to read. Is there a way to combine multiple variables within one “defaults read” - and/or - is there a way to do multiple shell requests within one “do shell script” request?

(Edited to fix error in the script)

To use one shell call separate your commands with a “;” the returning result is given back 1 result per line so for quick reference set your variable to the paragraphs of result.

So for example…

set vars to paragraphs of (do shell script "defaults read com.My.Script 'firstVariableToRead';defaults read com.My.Script 'secondVariableToRead'")

set foo to paragraph 1 of vars
set bar to paragraph 2 of vars

When I try to pull the variables out using the above code, it always says it can’t get paragraph 2 of vars, even when I reverse the read requests, or if I add a third part to the variable.

Also, is it actually faster to combine the two than doing two separate do shell script requests? I know the shell has to “launch” in the background before it can actually be done the first time (causing a speed hit on your script), but does the speed hit affect each separate request, or just the initial one? In the case of two do shell script requests, does the first shell “close” right afterward only to be reopened on the second request, or does the shell stay “open” in memory for a period of time or something?

First it may be better to just read the whole plist in one go.
Then pull the parts you need.

set vars to paragraphs of, takes each paragraph found in the result and puts it in vars as an item.

set vars to paragraphs of (do shell script "defaults read com.My.Script ")

set foo to item 1 of vars
set bar to item 2 of vars

Paragraphs is actually being used as a \r delimiter. So what this does is actually creates a list. So you want to do the following.

set foo to item 1 of vars
set bar to item 2 of vars

You could do it the other way too though

set vars to do shell script "defaults read com.My.Script 'firstVariableToRead';defaults read com.My.Script 'secondVariableToRead'"
set foo to paragraph 1 of vars
set bar to paragraph 2 of vars

As for your other questions, honestly I don’t know, but when Im trying to optimize code I generally cut out "tell"s and “do shell script” as much as possible.

I’m not getting the results you guys are saying when I set vars to paragraphs and then pull using items - each item is set as each character of vars, not each paragraph. And since it’s an array, foo becomes “{” and bar becomes the space after the bracket…

This seems to be working correctly - pulling each item from the plist, instead of each character one at a time.

I like the idea of this, but it seems that would be a whole tutorial in itself on how to parse the entire pulled plist file for use by my script, and correctly reference all of the items in the plist file as variables (they come through as full “key = value;” lines within vars).

Not to mention how to write the plist in the first place so I can guarantee the order of the variables in it. But if I could figure that out, it would seem to be less overhead in terms of shell requests. I assume this is a fairly common way of addressing plist based preferences - are there any tutorials for grabbing the whole plist and using it?

Actually I just remembered, apple introduced this in Leopard.
propertylists.html

They have a example script on the page to create and write to a plist.

Below is one I worked out to read it.

tell application "System Events"
	set the plistfile_path to "~/Desktop/com.My.Script"
	
	set firstVariableToRead to value of property list item "firstVariableToRead" of contents of property list file plistfile_path
	set secondVariableToRead to value of property list item "secondVariableToRead " of contents of property list file plistfile_path
end tell