Working with one of our enterprise clients recently I needed to use an array in a bash script.
This was because we wanted to read a load of separate values from AD and then perform a different task on the results. I had some memories using arrays with Objective-C but it took a bit of working out so I thought I’d share what I found.
The Requirement
We were working on a script to mount network drives based on AD group membership. The only oddity was the shared drive URLs were being stored in the description fields of the AD group records. We needed to check the groups the user was a member of and mount each of the respective drives. This particular client had in excess of 4000 group records so hard coding values definitely wasn’t an option!
Bash Array Basics
It’s probably a good idea at this point to run through a few basics with arrays in bash. This isn’t a definitive guide but covers the core elements we used in our script.
Arrays are quite similar to standard unix variables, the key difference is the use of brackets:
myArray=(value)
This would of course only store one value in the array so not much more use than a variable.
The power is when you want to store multiple values:
myArray=(value1 value2 value3)
As you can see you add multiple values by using a space as the separator. If you want white space in an array entry enclose it in quotes (‘value 1’ ‘value 2’).
If you wanted to add more values later you can use the + sign:
myArray+=(‘value4’)
myArray+=(‘value5’)
To read the values back you can use either an @ symbol:
echo ${myArray[@]}
Or use a number to read back a specific entry:
echo ${myArray[1]}
(It is worth noting at this point that arrays start at 0 so the first entry isn’t 1, its 0)
The Solution
We started off reading the memberOf attribute in AD and used sed & cut to get the group name.
The resulting values were put into an array called “adGroups”.
adGroups=($(dscl /Active Directory/AD-DOMAIN/All Domains -read /Users/$USER memberOf | cut -d, -f1 | sed 's|CN=||g'))
Once we had these values we used a for loop to cycle through the array, reading the description fields of each of the groups and mount the resulting URLs.
for group in "${adGroups[@]}” # This line starts the loop, reading the array values and setting the result as a variable called “group"
do
groupMount=$(dscl /Active Directory/AD-DOMAIN/All Domains -read /Groups/$group Comment | sed 's|Comment: ||g' | sed 's::/:g' | sed 's/ ////g' | tr -d 'n' | sed 's/ /%20/g’)
# The above line creates a new variable that reads the Comment attribute of the AD group,
# the uses sed (a lot) to strip out unwanted text and convert backslashes into forward slashes
mkdir /Volumes/$group
# The above line creates the mount point for the network drive
mount -t smbfs //$@$groupMount /Volumes/$group
# The above line performs the actual drive mount (using Kerberos)
done
This script is a bit cut down, leaving out logging and error checking but demonstrates the use of the array in this case.
If you would like more information about Bash Scripting, download our free whitepaper.