Script Exit Code - Forcing a policy log to show up as a "Problem"

AKuzenkov
New Contributor III

Hello,

I'm working on a script which will allow you to copy files/folders to an end user's Mac. I've noticed that scripts which error out are flagged in red in the logs for the policy. What determines if a script errored out and is there anyway to force that?

In this script I run a check to see if the destination path exists. If it does not, the script terminates with a non-zero exit code. When such an event occurs I'd like it highlighted as a Problem so that I can see which machines did not successfully copy a file. After testing it a few times on a machine where I knew the destination path did not exist, the logs were marked as successful even though the exit code was non-zero.

1 ACCEPTED SOLUTION

mm2270
Legendary Contributor III

This question came up recently in a Feature Request thread. While I don't know all the keywords the jamf binary will look for to determine a failure, I know "error" is one of them. These get read from stdout, which would include anything that gets echoed back in a shell script, as an example.

So the trick then is to use that exit status of your script, and if its not "0", do something like:

echo "error: script failed"

As long as its being echoed out with a keyword the jamf binary will see, it should correctly identify it as an unsuccessful script run.

Edit: I just ran a couple of quick tests with a bogus script that simply echoed out a variable $4 assigned to the script. "failed" and "failure" also both get picked up by the policy as a problem. When I enter "passed" as the variable to echo, it shows as a successful run.
So so far, error, failed, and failure are 3 keywords you can use when checking exit status and reporting it back. I'm not sure what other keywords it might look for though, but those 3 should be enough.

View solution in original post

13 REPLIES 13

mm2270
Legendary Contributor III

This question came up recently in a Feature Request thread. While I don't know all the keywords the jamf binary will look for to determine a failure, I know "error" is one of them. These get read from stdout, which would include anything that gets echoed back in a shell script, as an example.

So the trick then is to use that exit status of your script, and if its not "0", do something like:

echo "error: script failed"

As long as its being echoed out with a keyword the jamf binary will see, it should correctly identify it as an unsuccessful script run.

Edit: I just ran a couple of quick tests with a bogus script that simply echoed out a variable $4 assigned to the script. "failed" and "failure" also both get picked up by the policy as a problem. When I enter "passed" as the variable to echo, it shows as a successful run.
So so far, error, failed, and failure are 3 keywords you can use when checking exit status and reporting it back. I'm not sure what other keywords it might look for though, but those 3 should be enough.

donmontalvo
Esteemed Contributor III

Another option using logging....

Add variable to script:

packagename="mypackage"

...and...

#-------------------------------------------------------
# Logging
#-------------------------------------------------------
logFile="/private/var/log/"$packagename".log"
log () {
echo $1
echo $(date "+%Y-%m-%d %H:%M:%S: ") $1 >> $logFile
}

Add log commands to capture the errors...then peruse /private/var/log/mypackage.log file for errors.

Don

--
https://donmontalvo.com

nessts
Valued Contributor II

or write to syslog
logger "my message"
tail -1 /var/log/system.log
Jul 24 15:32:17 HPES-nesstodd nesstodd[60009]: my message

AKuzenkov
New Contributor III

mm2270's suggestion worked.

I liked the other two as well, something to keep handy for future use, but in this instance they wouldn't work since logging to a local file would then require going into each machine individually and reviewing the log or running an additional script to fetch the log and store it on a central server.

Thanks everyone!

AKuzenkov
New Contributor III

Here is the script if anyone's interested.

#!/bin/sh

##############################################################
# NAME
#   fileCopy.sh -- Copy files and folders from CasperShare/Files to end user's hard drive.
#
# SCRIPT PARAMETERS
#
# $1 - mountPoint           $2 - Computer Name          $3 - Username   
# -------           
# $4 - Name of the file/directory to copy
# $5 - Path that you're copying to
#
##############################################################
#
# VARIABLES & PARAMETERS
#
##############################################################

sourceFile=$4
destPath=$5
sourcePath="/Volumes/CasperShare/Files"

##############################################################
# 
# SCRIPT CONTENTS
#
##############################################################

# Check to see if source file/folder exists
if [ ! -f "$sourcePath/$sourceFile" ] && [ ! -d "$sourcePath/$sourceFile" ]; then
    echo "Error: SOURCE does not exist!";
    exit 1
fi

# Check if source folder is a file, else it's a directory
if [ -f "$sourcePath/$sourceFile" ]; then
    if [ ! -d "$destPath" ]; then
        echo "Error: Destination path does not exist!";
        exit 1
    fi
    # Check if file already exists to prevent over-writing.
    if [ -f "$destPath/$sourceFile" ]; then
        echo "Error: Destination path already contains FILE "$sourceFile"";
        exit 1
    fi
    echo "Copying FILE "$sourceFile" to "$destPath"";
    cp "$sourcePath/$sourceFile" "$destPath";
    chmod 777 "$destPath/$sourceFile";
else
    if [ ! -d "$destPath" ]; then
        echo "Error: Destination path does not exist!";
        exit 1
    fi
    # Check if folder already exists to prevent over-writing.
    if [ -d "$destPath/$sourceFile" ]; then
        echo "Error: Destination path already contains DIRECTORY "$sourceFile"";
        exit 1
    fi
    echo "Copying DIRECTORY "$sourceFile" to "$destPath"";
    cp -R "$sourcePath/$sourceFile" "$destPath";
    chmod -R 777 "$destPath/$sourceFile";
fi 

exit 0

mgarman
New Contributor III

I want my script, when it fails, to show as a fail in the Logs list AND to send JAMF Error message. I have my Email notifications set to notify me when: Error occurs when policy runs

I put in my script:

echo "error: script failed"
exit 1

The log shows it as a failure, but it doesn't send a JAMF Error Message. Any way to do that?

karthikeyan_mac
Valued Contributor

Hi ,

JAMF has mentioned in release notes that now policy logs takes the script exit value. I have a script to run after which has if else statement but if I use "exit 1" the policy log still shows as success. the policy should fail based on the exit 1 value in the else statement of the script.

Thanks & Regards,
Karthikeyan

krispayne
Contributor

exit 1 and echo "something something failure" do not currently make a policy fail on Jamf Pro 10

krispayne
Contributor

Jamf support told me to go to Jamf Nation to find out about how to get their product's policies to recognize Bash exit codes. Anyone able to figure out how to do this in Jamf 10?

Look
Valued Contributor III

I wonder if having the script kill itself would do it...

krispayne
Contributor

I suppose you could do a kill $$ or pipe to a die function or something, but that's designing around the problem I think. I could have sworn the JSS could tell at least whether a script within a policy was 0 or 1

greg_sheppard_k
New Contributor

-- (wrong account)

gregsheppard
New Contributor II

@krispayne, did you figure out how to make a policy exit early?

Thanks!