Hi i'm tryin to write a script to check software version. I want to pass my own variables, which are name of the Application and Version.

Here's a copy. It's not working for me currently... i'm a noob and i'm pretty sure it has to do with syntax.

Any input is appreciated.

Thanks, Paul

#/bin/sh

#Enter the Name of the Application here
ApplicationName=/Applications/FakeApp.app
ApplicationVersionNumber=1.0
echo $ApplicationName

#Check if Directory Exist
if [ ! -d $ApplicationName ]; then
            echo $ApplicationName "is not installed"
            exit 123456
fi
echo $ApplicationName " is installed"

# Check Version
VersionCheck=`cat $ApplicationName/version.plist | grep $ApplicationVersionNumber`
echo $VersionCheck
if [ ${#VersionCheck} != 0 ]; then
echo $VersionCheck
echo $ApplicationName $ApplicationVersion Number "is Installed"
exit 0
fi
echo $ApplicationName $ApplicationVersion Number "is NOT Installed"

exit 1

Solution 1:

There is really only one syntax mistake that you made. You put a space before Number in $ApplicationVersionNumber. Most apps don't have a version.plist file, but they always have the version in their Info.plist.

Here is a fixed version of the script with a few improvements:

#!/bin/sh

ApplicationName=/Applications/FakeApp.app
ApplicationVersionNumber=1.0
echo $ApplicationName

#Check if Directory Exist
if [ ! -d $ApplicationName ]; then
    echo "$ApplicationName is not installed"
    exit 123456
fi
echo "$ApplicationName is installed"

# Check Version
VersionCheck=`plutil -p "${ApplicationName}/Contents/Info.plist" | grep "CFBundleShortVersionString.*$ApplicationVersionNumber"`
echo $VersionCheck
if [ ${#VersionCheck} != 0 ]; then
    echo "$ApplicationName $ApplicationVersionNumber is Installed"
    exit 0
fi
echo "$ApplicationName $ApplicationVersionNumber is NOT Installed"
exit 1
  • It uses plutil -p instead of cat, since plutil can print out a nice, readable version of the plist even if it isn't in XML form.
  • It greps for the key (CFBundleShortVersionString), .*, and then the value. This is better because you don't want it to trigger on things like LSMinimumSystemVersion.
  • I also added more quotes because I like quotes and things are (usually) less likely to break that way.

I would have written it like this:

#!/bin/bash
app_path="$1"
desired_version="$2"

#Get the line, regardless of whether it is correct
version_line=$(plutil -p "${app_path}/Contents/Info.plist" | grep "CFBundleShortVersionString")
if [[ $? -ne 0 ]]; then
    version_line=$(plutil -p "${app_path}/Contents/Info.plist" | grep "CFBundleVersion")
    if [[ $? -ne 0 ]]; then #if it failed again, the app is not installed at that path
        echo "$app_path not installed at all"
        exit 123456
    fi
fi
#Some text editing to get the real version number
real_version=$(echo $version_line | grep -o '"[[:digit:].]*"' | sed 's/"//g')
if [ "$real_version" = "$desired_version" ]; then
    echo "$app_path $desired_version is installed"
    exit 0
fi
echo "${app_path}'s version is $real_version, not $desired_version"
exit 1

The advantage of this is it checks the actual version string, so if you put 1.3 and it's 1.3.1, it reports that it is a different version. $1 and $2 are the command-line arguments that are passed like ./script.sh '/Applications/FakeApp.app' '1.3'

Also, the other would count as correct on 1.1 for 121 because grep counts the . as a wildcard.

Solution 2:

You can also use AppleScript or defaults:

$ osascript -e 'version of app "TextEdit"'
1.9
$ defaults read /Applications/TextEdit.app/Contents/Info.plist CFBundleShortVersionString
1.9

You can use AppleScript or mdfind to find the path of an application:

$ osascript -e 'posix path of (path to app "textedit")'
/Applications/TextEdit.app/
$ mdfind 'kMDItemContentType=com.apple.application-bundle&&kMDItemFSName=TextEdit.app'
/Applications/TextEdit.app