Error in Policy running a script

jellingson
New Contributor II

I have a policy setup that is scoped to a smart computer group consisting of only MacBooks. The policy is setup to create a shortcut to a script located in the top level of the directory. The policy runs a script

#!/bin/sh

cd /Users/$3/Desktop

if [ ! -L "Backup.sh" ]
then
  ln -s /Backup.sh
else
  exit 0
fi

to create an Alias to /Backup.sh on the users desktop. The script works with out issue on most computer but every once in a while I will get a failed policy showing:

Executing Policy Backup Shortcut Running script Create Backup Shortcut... Script exit code: 1 Script result: ln: ./Backup.sh: File exists Error running script: return code was 1.

Does anyone have any idea why this would be happening? If I run the script locally there are no issues and usually if I force the policy to run again on the erred machine it runs without issue. Any help is appreciated
Attached is the trigger settings for the policy as well
e3dfe0fbb5bf4034844fec802e306352

1 ACCEPTED SOLUTION

sean
Valued Contributor

@jellingson

There appears to be a couple of things to address here if I understand you correctly.

  • The script is checking for the existing of a file against the existence of a link. (unlike your original script)
  • I would specify both source and destination (although this shouldn't be required if you choose to cd.
  • Could some of these be Finder aliases instead of unix symbolic links

Where it may be going wrong is the difference between a unix link and a Finder alias. A link created by Finder is not understood by unix. In Terminal, it will show as a file, whilst in Finder it will act more like a directory. You will not be able to use the command line to cd into a Finder alias either, it thinks it is a file and it is a file. If you look at the metadata of the file instead, you can see as much:

The below is a Finder alias.

ls -al ~/Desktop/ | grep testlink
-rw-r--r--@  ... testlink

mdls ~/Desktop/testlink -name kMDItemKind
kMDItemKind = "Alias"

Your original script was more correct, however, you may need further testing.

Perhaps something like:

#!/bin/bash

users_desktop="/Users/$3/Desktop"
users_backup="${users_desktop}/Backup.sh"

if [ -e "$users_backup" ]
then
        finder_item_kind=`mdls "$users_backup" -name kMDItemKind  | awk -F """ '{print $(NF-1)}'`

        if [[ "$finder_item_kind" == "Alias" ]]
        then
                echo "Finder Alias"
        else
                if [ -L "$users_backup" ]
                then
                        echo "Link exists"
                else
                        echo "Not Finder alias or link, but file exists"
                        exit 2
                fi
        fi
else
        ln -s /Backup.sh "$users_backup"
fi

exit 0

View solution in original post

11 REPLIES 11

Look
Valued Contributor III

Doesn't ln need two arguments? or does it default to the current directory if no target is specified? Might find some versions of OS X require you to specify the link location as well.

jellingson
New Contributor II

The command seems to work fine. It's the If statement that isn't running properly I believe. The error is what comes up when you run ln -s and the file is already present, but the ln command should not be running if the file is already there, That's what the If statement is for.

brad
Contributor

-L is checking for a symbolic link. There is a possibility that backup.sh exists on the desktop but is a file instead of an alias.

-Brad

jellingson
New Contributor II

That could be the issue I will look in to that! Thank you

jellingson
New Contributor II

So does anyone know of a way to check for an Alias created in Finder by right-clicking>"Make Alias"? The script works fine if the desktop icon is a Symbolic Link but not if it is an Alias created this way and I have been unable to find a way to check for Alias

jellingson
New Contributor II

I figured out the issue. -L was not checking for an Alias file and the quotes in the if statement seem to have been causing issues. New script checks for a file of any type called Backup.sh

#!/bin/sh

cd /Users/$3/Desktop

if [ ! -f Backup.sh ]
then
  ln -s /Backup.sh
else
  exit 0
fi

jellingson
New Contributor II

It seemed like changing the script a little bit was the solution but after some more testing that no longer seems to be the case. The edited script runs without problem on all computers locally but when ran through the JSS continues to give the error

Executing Policy Backup Shortcut Running script Create Backup Shortcut... Script exit code: 1 Script result: ln: ./Backup.sh: File exists Error running script: return code was 1.

sean
Valued Contributor

@jellingson

There appears to be a couple of things to address here if I understand you correctly.

  • The script is checking for the existing of a file against the existence of a link. (unlike your original script)
  • I would specify both source and destination (although this shouldn't be required if you choose to cd.
  • Could some of these be Finder aliases instead of unix symbolic links

Where it may be going wrong is the difference between a unix link and a Finder alias. A link created by Finder is not understood by unix. In Terminal, it will show as a file, whilst in Finder it will act more like a directory. You will not be able to use the command line to cd into a Finder alias either, it thinks it is a file and it is a file. If you look at the metadata of the file instead, you can see as much:

The below is a Finder alias.

ls -al ~/Desktop/ | grep testlink
-rw-r--r--@  ... testlink

mdls ~/Desktop/testlink -name kMDItemKind
kMDItemKind = "Alias"

Your original script was more correct, however, you may need further testing.

Perhaps something like:

#!/bin/bash

users_desktop="/Users/$3/Desktop"
users_backup="${users_desktop}/Backup.sh"

if [ -e "$users_backup" ]
then
        finder_item_kind=`mdls "$users_backup" -name kMDItemKind  | awk -F """ '{print $(NF-1)}'`

        if [[ "$finder_item_kind" == "Alias" ]]
        then
                echo "Finder Alias"
        else
                if [ -L "$users_backup" ]
                then
                        echo "Link exists"
                else
                        echo "Not Finder alias or link, but file exists"
                        exit 2
                fi
        fi
else
        ln -s /Backup.sh "$users_backup"
fi

exit 0

jellingson
New Contributor II

@sean Thank you for the information I will go ahead and give that a try and see what I can come up with. It just seems strange that when running the -f it will find the file whether it is a Finder Alias or a Symbolic Link when the script is ran locally but when it is ran by a policy through the JSS it seems to always fail. Is the script being ran any differently through the JSS or why would I be getting two different outcomes from the same script on the same computer?

Thanks for the help

sean
Valued Contributor

@jellingson

-f should not return true on a link, but should return true on a Finder alias as a Finder alias in unix is a regular file.

Something is of issue before JSS if -f is returning true on a symbolic link. You may wish to check that.

Bash if options

brad
Contributor

@jellingson

The main difference you could see in running a script locally vs running it through Casper is the user it is executing as. Casper will be executing your script as root. You might try running it as root on the local machine to see if it produces the same results. The other thing you may want to check is that the interpreter directive is the same in the JSS as in your test device. #!/bin/sh and #/bin/bash may produce different results.

-Brad