bash shell script arrays?

mosx86

Registered
I'm working on a shell script (#!/bin/sh) that uses defaults to read the com.apple.dock plist and gather the persistent-apps and persistent-others into arrays, however because some of the Applications have spaces in them, they are entered as separate entities in the array.

I've tried the following but with no luck...

Code:
#!/bin/sh

# Arrays
currentPersistentApps=( `defaults read com.apple.dock persistent-apps | grep CFURLString | grep -v CFURLStringType | awk '{print $3, $4}' | sed 's/;//' | sed 's/[ \t]*$//' | sed '/\ /s/\ /\\\ /g' | tr '\n' ' '` )

# Output
echo "${currentPersistentApps[$1]}"

Code:
#!/bin/sh

# Variables
currentPA=`defaults read com.apple.dock persistent-apps | grep CFURLString | grep -v CFURLStringType | awk '{print $3, $4}' | sed 's/;//' | sed 's/[ \t]*$//' | sed '/\ /s/\ /\\\ /g' | tr '\n' ' '`

# Arrays
currentPersistentApps=( `echo "$currentPA"` )

# Output
echo "${currentPersistentApps[$1]}"

Both of the above examples end up having spaces within Application names cutting the Application name into 2 array entities (i.e. "/Applications/Internet\ Explorer.app/" ends up as "/Applications/Internet\" and "Explorer.app/")

If I declare the array in the manner listed below, the spaces within applications names are honored. What I don't understand is that the output of the defaults command exactly matches what is manually declared.

Code:
#!/bin/sh

# Arrays
currentPersistentApps=( "/Applications/Safari.app/" "/Applications/Mail.app/" "/Applications/Server/Server\ Admin.app/" "/Applications/Server/Workgroup\ Manager.app/" "/Applications/Server/Server\ Monitor.app/" "/Applications/iTunes.app/" "/Applications/Utilities/Terminal.app/" "/System/Library/CoreServices/Screen\ Sharing.app/" "/System/Library/CoreServices/Kerberos.app/" "/Applications/TextWrangler.app/" "/Applications/Adium.app/" "/Applications/Time\ Machine.app/" "/Applications/TextEdit.app/" )

# Output
echo "${currentPersistentApps[$1]}"

Many thanks in advance!
 
In your awk statement, can you print out a leading and trailing double-quote around each path and application name string? It seems the default behavior is to split the array on spaces, but if you manually input the double-quotes (like you do with your manual array), then it may work.
 
The output of:

Code:
defaults read com.apple.dock persistent-apps | grep CFURLString | grep -v CFURLStringType | awk '{print $3, $4}' | sed 's/;//' | sed 's/[ \t]*$//' | sed '/\ /s/\ /\\\ /g' | tr '\n' ' '

is:

Code:
"/Applications/Safari.app/" "/Applications/Mail.app/" "/Applications/Server/Server\ Admin.app/" "/Applications/Server/Workgroup\ Manager.app/" "/Applications/Server/Server\ Monitor.app/" "/Applications/iTunes.app/" "/Applications/Utilities/Terminal.app/" "/System/Library/CoreServices/Screen\ Sharing.app/" "/System/Library/CoreServices/Kerberos.app/" "/Applications/TextWrangler.app/" "/Applications/Adium.app/" "/Applications/Time\ Machine.app/" "/Applications/TextEdit.app/"

Are you suggesting that I modify it to be something like this:

Code:
""/Applications/Safari.app/"" ""/Applications/Mail.app/"" ""/Applications/Server/Server\ Admin.app/""
 
Oh, hell, that is strange that the bash array would still "process" the spaces within the quotes.

No, I'm not suggesting you put double-double quotes around them... that would just make things worse, methinks.

After some research, it seems that bash arrays like string elements to be enclosed in single-quotes, not double-quotes. If you change your code to produce single-quoted strings, I'm thinking it should work...
 
Unfortunately single quotes produce the same results. I'm beginning to think its more an issue with redirecting the output of the commands into the array. I've even tried writing the defaults ... ... command out to a file and catting the file into the array with no luck.

I was hoping to do this without using temp files...
 
Oh, hell, that is strange that the bash array would still "process" the spaces within the quotes.

No, I'm not suggesting you put double-double quotes around them... that would just make things worse, methinks.

After some research, it seems that bash arrays like string elements to be enclosed in single-quotes, not double-quotes. If you change your code to produce single-quoted strings, I'm thinking it should work...

Pestered a *nix guru of mine (owe him a bottle of single malt scotch) and it turns out I had to set IFS to newline.

Here is a working script:

Code:
#!/bin/sh

IFS=$'\n'

thearray=(`defaults read com.apple.dock persistent-apps | grep CFURLString\" | awk '{$1=$2="";gsub(";","");gsub("\"","");gsub("\ \ ","");gsub("\ ","\/\ ");print}'`)

echo "${thearray[0]}"
echo "${thearray[1]}"
echo "${thearray[2]}"
echo "${thearray[3]}"

exit 0
 
Back
Top