Casper remote shows "failures" with custom bash scripts

acdesigntech
Contributor II

Hi everyone,

I tend to script a lot of tasks that are eventually run through Casper remote by our technicians. A lot of times the script will complete and Casper Remote will show a "failure" (Error Occurred) for something simple like trying to run an rm command on a file that isn't there in the first place. I've tried simply redirecting stderr to /dev/null, but this isn't really "not failing," it's just not complaining in the logs about it.

Has anyone run into this issue and is there a way to fool Casper into seeing failures as successes? -- This would only be for stuff like removing certain files that need to be removed if they exist, if not, no big deal, and a failure here wouldn't affect operation of the computer, etc.

TIA!
Andrew

2 ACCEPTED SOLUTIONS

JRM
Contributor

It is "best practice" to check for existence first. The piping to true is definitely the dirty way to do it.

If you just want to keep your remove on one line you can condense the if statement:

#!/bin/sh

# Test if a directory exists
if [ -d /Applications ] ; then echo "Applications folder exists."; fi

# Test if a FILE exists and is a regular file (not a symbolic link)
if [ -f /somefile ] ; then echo "somefile exists."; fi

# To just test for a FILE existing:
if [ -e /somefile ] ; then echo "somefile exists."; fi

# if you wanted to remove "somefile" you would use:
if [ -e /somefile ] ; then echo "somefile exists- removing."; rm /somefile; fi

# or simply - without the echo out put
if [ -e /somefile ] ; then rm /somefile; fi

View solution in original post

rmanly
Contributor III

everything JRM said + the following.

If you have a bunch of files to get rid of you can put them in an array first and get rid of them that way. In rare cases rm can complain that it has been given too many arguments so it is best to do it this way (for other reasons too).

See my Flash removal script here https://jamfnation.jamfsoftware.com/discussion.html?id=3929.

In bash you can also do a nice little trick for something as simple as removing files to save from having to do an entire if/then/else construct.

[[ -e /path/to/some/file ]] && rm /path/to/some/file

or the opposite

[[ -d /does/this/dir/exist ]] || mkdir -p /does/this/dir/exist
# not the best example since mkdir -p is well behaved anyway

See the URL below for an explanation.
http://mywiki.wooledge.org/BashGuide/TestsAndConditionals

View solution in original post

7 REPLIES 7

talkingmoose
Moderator
Moderator

End your script with "exit 0". That value should be passed back to Casper when the script is complete.

One way to handle this issue would be to test whether you need to run a command. If you're needing to delete a folder, for example, but know that folder may or may not exist then use something like:

#!/bin/sh

if [ -d /Applications ] ; then
    echo "Applications folder exists."
    # run extra commands here
else
    echo "Applications folder does not exist."
fi

exit 0

In this case the "-d" tests for the existence of the Applications "directory" at the root of the drive.

You can use "-f" to test for the existence of a file or "-e" to test for the existence of either.

JRM
Contributor

You could also try pipe your results to true, which will set the error level to 0. I'm not 100% sure if this will hide the error level of the rm command from the casper script engine.

#!/bin/sh
rm somefile | true

acdesigntech
Contributor II

Thanks! I'll try both of those suggestions tomorrow.

I wasn't aware of piping to true, interesting...

BTW, forgot to mention that my fallback was to add checks for file existence before running certain commands, but was hoping for a quick and dirty solution. Alas, the right way is yet again the best way ;)

JRM
Contributor

It is "best practice" to check for existence first. The piping to true is definitely the dirty way to do it.

If you just want to keep your remove on one line you can condense the if statement:

#!/bin/sh

# Test if a directory exists
if [ -d /Applications ] ; then echo "Applications folder exists."; fi

# Test if a FILE exists and is a regular file (not a symbolic link)
if [ -f /somefile ] ; then echo "somefile exists."; fi

# To just test for a FILE existing:
if [ -e /somefile ] ; then echo "somefile exists."; fi

# if you wanted to remove "somefile" you would use:
if [ -e /somefile ] ; then echo "somefile exists- removing."; rm /somefile; fi

# or simply - without the echo out put
if [ -e /somefile ] ; then rm /somefile; fi

rmanly
Contributor III

everything JRM said + the following.

If you have a bunch of files to get rid of you can put them in an array first and get rid of them that way. In rare cases rm can complain that it has been given too many arguments so it is best to do it this way (for other reasons too).

See my Flash removal script here https://jamfnation.jamfsoftware.com/discussion.html?id=3929.

In bash you can also do a nice little trick for something as simple as removing files to save from having to do an entire if/then/else construct.

[[ -e /path/to/some/file ]] && rm /path/to/some/file

or the opposite

[[ -d /does/this/dir/exist ]] || mkdir -p /does/this/dir/exist
# not the best example since mkdir -p is well behaved anyway

See the URL below for an explanation.
http://mywiki.wooledge.org/BashGuide/TestsAndConditionals

acdesigntech
Contributor II

Ok, now the opposite... I have a function that tests whether a given user folder exists or not before any further processing can be done in the script. If the folder does not exist, the script exits and makes it very clear what needs to be done to avoid that message in the future, but it should be considered a failure and exits with status 1. However Casper considers this a success and shows it under Successful in Remote, leading me to believe that any integer exit code in the script will trigger a success (I also tried exiting with -1).

JRM
Contributor

If you are already testing and know you've had a non-existant folder, you could add "false" just before you exit the script. This will set the errorlevel to 1 in a way that should be picke up correctly.

#!/bin/bash

# set errorlevel to 0 using true
true

# echo the error level to se the result of true
echo $?

# the result should be 0


#Set the error level to 1 using false
false

# echo the error level to see the result of false
echo $?

# the result should be 1


# echo the error level again se the result of echo
echo $?

# the result should be 0

You can use the "echo $?" in your script to see if there is an error or not when the script exits. I'm not sure of the behavior [of false] within a function, but I would imagine the errorlevel *should* still get to casper.