How can I check for an error when reading from a plist in a script?

jhuls
Contributor III

I'm writing an EA that has the following line...

migrationStatus=`defaults read /Library/path/to/com.****.****.plist "Migration"`

If the plist or key isn't there, I get the following error message and $migrationStatus is set to nothing.

The domain/default pair of (/Library/path/to/com.****.****.plist, Migration) does not exist

I'm not a super scripter by any means. How can I handle this so that I can check against the file not existing or if the key is missing from the plist file?

2 ACCEPTED SOLUTIONS

alexjdale
Valued Contributor III

In bash, the variable $? contains the error code that was returned by the last command you ran. It would be 1 if defaults couldn't find the specified plist/entry, 0 if everything went fine.

If you include a check against $? immediately after the defaults command, you can branch your code that way.

If you want to perform a check for a file, you can put that into an if command:

if [ -f "path/to/file" ]; then
   echo "file exists"
else
   echo "file does not exist"
fi

View solution in original post

SeanA
Contributor III

@alexjdale 's idea is good.
Another related option: Let's say you run a defaults write command, then place the defaults read output into a variable. You can test to see if you have the intended value. Obviously, test.

    echo "Show Hard Drives on Desktop..."
    defaults write /Library/Preferences/com.apple.finder ShowHardDrivesOnDesktop -bool TRUE
    ShowHardDrivesOnDesktop=`defaults read /Library/Preferences/com.apple.finder ShowHardDrivesOnDesktop`
    echo "Confirming configuration..."
        if [ "$ShowHardDrivesOnDesktop" = "1" ]; then 
                echo "SUCCESS! Show Hard Drives on Desktop is configured properly."
            else
                echo "WARNING! Show Hard Drives on Desktop is NOT configured properly."
        fi

View solution in original post

6 REPLIES 6

alexjdale
Valued Contributor III

In bash, the variable $? contains the error code that was returned by the last command you ran. It would be 1 if defaults couldn't find the specified plist/entry, 0 if everything went fine.

If you include a check against $? immediately after the defaults command, you can branch your code that way.

If you want to perform a check for a file, you can put that into an if command:

if [ -f "path/to/file" ]; then
   echo "file exists"
else
   echo "file does not exist"
fi

SeanA
Contributor III

@alexjdale 's idea is good.
Another related option: Let's say you run a defaults write command, then place the defaults read output into a variable. You can test to see if you have the intended value. Obviously, test.

    echo "Show Hard Drives on Desktop..."
    defaults write /Library/Preferences/com.apple.finder ShowHardDrivesOnDesktop -bool TRUE
    ShowHardDrivesOnDesktop=`defaults read /Library/Preferences/com.apple.finder ShowHardDrivesOnDesktop`
    echo "Confirming configuration..."
        if [ "$ShowHardDrivesOnDesktop" = "1" ]; then 
                echo "SUCCESS! Show Hard Drives on Desktop is configured properly."
            else
                echo "WARNING! Show Hard Drives on Desktop is NOT configured properly."
        fi

jhuls
Contributor III

Thank you to you both!

bentoms
Release Candidate Programs Tester

@jhuls anohter alternative is the -z flag, this means "if null".

So could be used like:

if [ -z $migrationStatus ]; then
   echo "Nope"
else
   echo "$migrationStatus

jhuls
Contributor III

I've already implemented the other suggestion but thanks for posting that. I'm always interested in how many ways one can skin a cat so to speak.

pcrandom
Contributor

@jhuls: Looks like I'm a little late to the game, but here's what I came up with, using a different domain/key pairing that every Mac should have: com.apple.finder.plist (if you don't specify the path in the "defaults read" command, it looks in ~/Library/Preferences automatically) and AppleShowAllFiles (the key that controls where hidden files are visible in Finder).

#!/bin/bash

domainPlist="com.apple.finder.plist"
keyName="AppleShowAllFiles"
defaultsCmd="defaults read $domainPlist $keyName"

if ($defaultsCmd) > /dev/null 2>&1; then
    keyStatus=$($defaultsCmd)
else
    keyStatus="Not Found"
fi

echo "The keyStatus variable is set to "$keyStatus"."

By default the key does not exist, so the keyStatus variable will be set to "Not Found" if you run the script. If you set the key to YES or NO in advance, then the script will assign the keyStatus variable accordingly.

(If set to YES, then you can run "killall Finder" to relaunch the Finder and then you'll see hidden files in your Finder windows.)

Let me know if you have any questions. I'm just starting out as well and I find it fun and challenging to try to figure out how to get things done with shell scripting.