1

I have a plistbuddy command that I need to execute for 100 different users.

The value I have to enter for the 100 individual users depends on the hostname.

I was thinking I could use a csv that has a list of the hostnames/computernames and the corresponding plist value, then use a shell script to:

  1. Check for the hostname of the Mac
  2. Find the hostname in the csv
  3. find the value of the corresponding code needed for the plistbuddy command and save it to a variable
  4. insert that value into the plistbuddy command and execute, changing the value of the desired plist file.

The csv would just be formatted as:
hostname, code
hostname1, 2001
hostname2, 2002

Specifically the plist file is the printer preference plist file.

Here is the plistbuddy command:

/usr/libexec/PlistBuddy -c "Set :2ndfloor:com.apple.print.preset.settings:ManagementCodeValue 1001" ~/Library/Preferences/com.apple.print.custompresets.forprinter.CMI2ndFloorColor.plist

The value that needs to change depending on the hostname is the value "1001" in that command.

Those are the only elements; check hostname, find it in the csv, execute the plistbuddy command using the corresponding code in the csv.

Anyone have any good ideas for this? It would save hours and hours of GUI work.

2 Answers 2

2

Here's a three-line shell script for bash. Assume the CSV file is named hosts.csv.

h=`hostname -s`
c=`sed -nE -e "/^$h, ?/s/^.+, ?//p" hosts.csv`
/usr/libexec/PlistBuddy -c "Set :2ndfloor:com.apple.print.preset.settings:ManagementCodeValue $c" ~/Library/Preferences/com.apple.print.custompresets.forprinter.CMI2ndFloorColor.plist

The script sets the shell variables $h to the host name, and $c to the code that matches the host. Get the name of the host from the hostname command. Use $c in place of the value "1001" in the PlistBuddy command.

By default the hostname command returns domain information. Therefore if the CSV file has host names without domain information, use h=`hostname -s`, otherwise use h=`hostname`.

The sed command matches a line from the CSV file that starts with the $h host name followed by a comma and an optional space character. For the line that matches, sed removes everything but the code from the line.

4
  • excellent explanation. still learning all the syntax, but this makes sense. will report to let you know if it works in practice or not.
    – thursDave
    Jul 13, 2018 at 15:46
  • it totally worked. now, because we had to do all this based on current user, not hostname in the end, i just swapped out the hostname command with "/usr/bin/who | grep console | cut -d ' ' -f1" and changed $h to $u for readability, it still 100% worked
    – thursDave
    Jul 13, 2018 at 16:14
  • 1
    I'm glad the explanation helped even when you needed a change. @nohillside has a good idea to check the "code" in his answer. His If statement is an important improvement.
    – creidhne
    Jul 14, 2018 at 0:22
  • one thing i'm running into is that both this solution and the one below are actually causing the plist file xml to go out of whack. the managementcodevalue has a <string>9999</string> kind of format for its value. but after running the script, the xml formats as </string><string>9999 and the print dialog will error out. any idea why? if i just run the commands with a number instead of a variable this does not happen.
    – thursDave
    Aug 31, 2018 at 20:36
2

You can use awk to process the file and find the matching code value.

code=$(awk -F , '$1 == "'$(hostname -s)'" { print $2 }' hosts.csv)
if [[ -n "$code" ]]; then
    /usr/libexec/PlistBuddy -c "Set :2ndfloor:com.apple.print.preset.settings:ManagementCodeValue $code" ~/Library/Preferences/com.apple.print.custompresets.forprinter.CMI2ndFloorColor.plist
else
    echo "No code for $(hostname -s)"
fi

The awk part searches for the line where the first value is equal to the hostname and prints the second value of that line. As there might be no match, the if ... part ensures that PlistBuddy is only called if a code value was found.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .