Posted on 01-19-2017 11:39 AM
I'm trying to use an extension attribute to tell if a program is installed by looking at a few folders to see if the folder/files exist. It's reporting if it's Not Installed, but it's not telling me if it's installed. Am i doing something wrong?
#!/bin/bash
#xclient is a unix executable
if [ ! -f /usr/local/bin/xClient ]; then
echo "<result>Not Installed</result>"
#xmetering is a unix executable
if [ ! -f /usr/local/bin/xMetering ]; then
echo "<result>Not Installed</result>"
#snowclient.conf is a config file
if [ ! -f /etc/snowclient.conf ];then
echo "<result>Not Installed</result>"
#Snow software is a directory
if [ ! -d /Library/Application Support/Snow Software ]; then
echo "<result>Not Installed</result>"
else
echo "<result>Installed</result>"
fi
fi
fi
fi
Posted on 01-19-2017 11:51 AM
Another way is to create a smart group with the Criteria as Packages installed by Casper
Posted on 01-19-2017 12:02 PM
@CapU That was a million times easier. I got it setup in less than 5 minutes... Thanks!
Posted on 01-19-2017 01:18 PM
Glad I could help
Posted on 01-19-2017 02:00 PM
I know you've already gotten it done an easier way, but FYI - your script would only generate an "Installed" result for the EA if the Snow Software directory existed. The else is within the if ... fi for that check only. If you want the result to be "Installed" if all the conditions are met, I mean not met (since you're testing for the absence of the files), then you'd want the else at the top level:
#!/bin/bash
#xclient is a unix executable
if [ ! -x /usr/local/bin/xClient ]; then
echo "<result>Not Installed</result>"
exit 0
#xmetering is a unix executable
if [ ! -x /usr/local/bin/xMetering ]; then
echo "<result>Not Installed</result>"
exit 0
#snowclient.conf is a config file
if [ ! -f /etc/snowclient.conf ];then
echo "<result>Not Installed</result>"
exit 0
#Snow software is a directory
if [ ! -d /Library/Application Support/Snow Software ]; then
echo "<result>Not Installed</result>"
exit 0
fi #Snow software is a directory
fi #snowclient.conf is a config file
fi #xmetering is a unix executable
else
echo "<result>Installed</result>"
fi #xclient is a unix executable
exit 0
I'm sure there are more efficient ways of doing the above, but I just moved your pieces around. I changed some of the tests to -x since you want to know if some files were executable. I also had the script exit after echoing one of the "Not Installed" results, since it doesn't need to process the rest of the checks.
If it's the case that the result should be "Not Installed" if any of the files/directories do not exist, then you don't actually need to nest the if statements, which makes it an easier read. You can also replace the repetitive results echoing and exiting with a function, and leaving the last echo line for "Installed" will only run if all the if conditions are not met.
#!/bin/bash
function ea_not {
echo "<result>Not Installed</result>"
exit 0
}
#xclient is a unix executable
if [ ! -x /usr/local/bin/xClient ]; then
ea_not
fi
#xmetering is a unix executable
if [ ! -x /usr/local/bin/xMetering ]; then
ea_not
fi
#snowclient.conf is a config file
if [ ! -f /etc/snowclient.conf ];then
ea_not
fi
#Snow software is a directory
if [ ! -d /Library/Application Support/Snow Software ]; then
ea_not
fi
echo "<result>Installed</result>"
exit 0
Just for fun, and because I'm still a novice at scripting, I made up a version of this second script using arrays and a for loop. No idea if this would work...
#!/bin/bash
filechecks=( "-x /usr/local/bin/xClient" "-x /usr/local/bin/xMetering" "-f /etc/snowclient.conf" "-d /Library/Application Support/Snow Software" )
for check in "${filechecks[@]}"
do
if [ ! "$check" ] ; then
echo "<result>Not Installed</result>"
exit 0
fi
done
echo "<result>Installed</result>"
exit 0
Posted on 01-19-2017 02:50 PM
Rather than excluding when something is missing, include if everything is present, it just seems cleaner...
With the way bash works it should still exit out at the first failed file without having to force exit the statement.
Alternatively do it the way it was done originally using or || instead. Although I do quite like the editable list of requirements in the loop version.
#!/bin/bash
if [ -x /usr/local/bin/xClient ] && [ -x /usr/local/bin/xMetering ] && [ -f /etc/snowclient.conf ] && [ -x /usr/local/bin/xMetering ] && [ -f /etc/snowclient.conf ] && [ -d /Library/Application Support/Snow Software ]; then
echo "<result>Installed</result>"
else
echo "<result>Not Installed</result>"
fi
Posted on 01-19-2017 04:44 PM
Thanks @Look, I originally thought of flipping it around from testing for the negative (also easier to talk about without getting confused) but I just stuck with the OP's original structure, in case s/he had a reason for the negative checks.
I like the array too. One question for you (or anyone with more scripting experience) would be whether the last item in the array, "-d /Library/Application Support/Snow Software", would need the escaping the spaces in the filename since it's included in quotes. I know in some cases, like paths with the scp command you actually have to use multiple escapes because as the command gets passed from system to system, it "uses up" each layer of escapes...
So I feel like when the array is slotted into the $check in the for loop, it might lose the quotes (though I did put "$check" in quotes too, per shellcheck.net's recommendation to prevent globbing and word splitting), so it's good to also escape with . However, I assume having too many escape "layers" isn't good either. I guess I could test it myself but just in case people knew off the top of their heads.
Posted on 01-19-2017 04:45 PM
Posted on 01-19-2017 04:49 PM
@pcrandom To be honest on the escape character I'm not certain how it will pass that. I have a personal preference for not using escape characters unless I need to and usually just use quote marks around it when I call it to ensure it reads as written.
I really don't play with arrays much at all though.
Posted on 01-19-2017 04:52 PM
Glad to help @bbot. I'm definitely a novice too, but I like coming across these and trying to "fix" them (especially as it's low risk since you already an alternative method to get what you needed). Definitely check out shellcheck.net, it's helped me a lot with my bash scripts. And There's definitely better threads out there to bookmark on creating EAs than with my examples. ;-)
Posted on 05-04-2020 08:13 PM
Sure glad I ran by this. I was using a Smart Group to determine if SNOW was installed by using the JSS installed packages criteria. However, if someone installed it and then uninstalled it, the computer would still populate the Smart Group - from what I'm seeing in my testing.
I used part of @Look's script above and tweaked it to my liking. I was able to pull in those with SNOW installed via Extension Attribute. Now, I have a more accurate Smart Group that I can use.
#!/bin/bash
if [ -x /opt/snow/snowagent ] && [ -f /opt/snow/snowagent.config ]; then
echo "<result>Installed</result>"
else
echo "<result>Not Installed</result>"
fi
Posted on 03-29-2021 07:59 PM
@bcbackes so I to am glad I found this as I was struggling with this and still to a degree am. So I have the one you see below:
#!/bin/bash
if [ -d /Library/Application Support/CrowdStrike/Falcon ] && [ -d /Applications/Falcon.app/Contents/Resources ]; then
echo "<result>Installed</result>"
else
echo "<result>Not Installed</result>"
fi
But it came back on a known good machine with not installed. So I thought ok break each one down and whats odd is that
/Library/Application Support/CrowdStrike/Falcon
Doesn't work and I'm wondering if thats due to SIP protection? Even on its own it shows no folder is "installed" but I can get to it without issue within finder or see it in terminal. Any thoughts?
Posted on 03-30-2021 11:43 PM
@daniel_ross Hi Daniel you will need to escape the space in 'Application Support'.
I've run your script with this change.
#!/bin/bash
if [ -d /Library/Application Support/CrowdStrike/Falcon ] && [ -d /Applications/Falcon.app/Contents/Resources ]; then
echo "<result>Installed</result>"
else
echo "<result>Not Installed</result>"
fi
It worked fine.
However as you are looking for directories one could have a false positive.
Could I suggest looking for the binary executable instead?
#!/bin/bash
if [ -d /Library/Application Support/CrowdStrike/Falcon ] && [ -x /Applications/Falcon.app/Contents/MacOS/Falcon ]; then
echo "<result>Installed</result>"
else
echo "<result>Not Installed</result>"
fi
I hope this helps.
Regards
Posted on 08-12-2022 05:57 AM
I know this is an old post but if someone comes across this and is looking to find a way to report back the version of SNOW that is installed on their Macs I was able to create this extension attribute to report that information back. If SNOW isn't installed it will report "Not Installed" instead. Hope this helps others!
#!/bin/bash
if [ -x /opt/snow/snowagent ]; then
version=$(/opt/snow/snowagent version)
echo "<result>$version</result>"
else
echo "<result>Not Installed</result>"
fi