AppleScript Execution Error - can't find script in non-default location

According to the AppleScript Language Guide – section 3 of quoted portion below. I should be able to put library scripts in a folder specified by the OSA_LIBRARY_PATH folder.

I have set my OSA_LIBRARY_PATH to ~\APPLESCRIPT\SCANGLOBAL2\Script Libraries using the command
Export OSA_LIBRARY_PATH=/Users/bcrow/APPLESCRIPT/SCANGLOBAL2/Script\ Libraries.

I checked that the environment variable had been changed by executing
printenv

which shows
OSA_LIBRARY_PATH=/Users/bcrow/APPLESCRIPT/SCANGLOGAL2/Script Libraries

After first testing that the attached script email_functions_lib3 standalone.scpt works if the library scripts are in ~\Library\Library Scripts, I copied the library scripts to the OSA_LIBRARY_PATH folder and renamed the originals.

When I run the program, the compiler throws an AppleScript Execution Error “Cant get script ‘UI_functions_lib’”

Is there some reason the Script Debugger compiler is not searching for script in the OSA_LIBRARY_PATH?

I want to keep libraries in a folder with my main AppleScript program because I am using Mercurial to control revisions, which will not work if the library files are off in some unassociated folder.

Excerpt from AppleScript Language Guide at
https://developer.apple.com/library/mac/documentation/AppleScript/Conceptual/AppleScriptLangGuide/conceptual/ASLR_script_objects.html#//apple_ref/doc/uid/TP40000983-CH207-SW6

Paragraph 3 Bolding added by me.Mac Developer LibraryDeveloper
Creating a Library
The basic requirement for a script to be a script library is its location: it must be a script document in a “Script Libraries” folder in one of the following folders. When searching for a library, the locations are searched in the order listed, and the first matching script is used:

  1. If the script that references the library is a bundle, the script’s bundle Resources directory. This means that scripts may be packaged and distributed with the libraries they use.
  2. If the application running the script is a bundle, the application’s bundle Resources directory. This means that script applications (“applets” and “droplets”) may be packaged and distributed with the libraries they use. It also enables applications that run scripts to provide libraries for use by those scripts.
  3. Any folders specified in the environment variable OSA_LIBRARY_PATH. This allows using a library without installing it in one of the usual locations. The value of this variable is a colon-separated list of paths, such as /opt/local/Script Libraries:/usr/local/Script Libraries. Unlike the other library locations, paths specified in OSA_LIBRARY_PATH are used exactly as-is, without appending “Script Libraries”. Supported in OS X v10.11 and later.
  4. The Library folder in the user’s home directory, ~/Library. This is the location to install libraries for use by a single user, and is the recommended location during library development.
  5. The computer Library folder, /Library. Libraries located here are available to all users of the computer.
  6. The network Library folder, /Network/Library. Libraries located here are available to multiple computers on a network.
  7. The system Library folder, /System/Library. These are libraries provided by OS X.
  8. Any installed application bundle, in the application’s bundle Library directory. This allows distributing libraries that are associated with an application, or creating applications that exist solely to distribute libraries. Supported in OS X v10.11 and later.

This is the text of the calling Applescript

use AppleScript version “2.4” – Yosemite (10.10) or later
use scripting additions
–BEGIN add for standalone
set FinalFilePathName_Passed to "EulerHD:Users:bcrow:Downloads:test PDF copy 2.pdf"
set POMessage to true
use libUIfunctionslib : script "UI_functions_lib"
use libserverfunctionslib : script “server_functions_lib”

property dialogchoiceList : libUIfunctionslib’s dialogchoiceList
property TestServerConnection : libserverfunctionslib’s TestServerConnection

set ServerNameStr1 to “xxxxx”
set UserNameStr1 to "xx”
set UserPswdStr1 to “xxxxx”
set ServerNameStr2 to “xxxx”
set UserNameStr2 to “xxx”
set UserPswdStr2 to “xxx”

TestServerConnection(ServerNameStr1, UserNameStr1, UserPswdStr1)
TestServerConnection(ServerNameStr2, UserNameStr2, UserPswdStr2)
–END add for standalone

set Email_RecipientsList to {}
set Email_AddressesList to {}

set EmailFullPathFileName to “Not Yet Defined"
set shortName to {”"}
set ChoiceList to {""}
set AddresseeCount to 0
set choiceK to “Not Yet Defined”

set EmailFullPathFileName to “ELC:Shared:IT:Scan Name Utility:Employee List.txt”

–set EmailFullPathFileName to “ELC:Shared:IT:Scan Name Utility:SNAFU email list.csv”

–open email file and create list of lines
–set fileHandle to (“EulerHD:Users:bcrow:Desktop:SNAFU email list.csv”)
–set fileHandle to open for access file "/Volumes/ELC/Shared/IT/Scan Name Utility/SNAFU email list.csv"
set fileHandle to (open for access file EmailFullPathFileName)
set theLines to paragraphs of (read fileHandle)
close access fileHandle
–close file after theLines is created

set addresseeListCount to count of theLines
set original_delimiters to text item delimiters
set text item delimiters to “,”

–>>emailGroup
set ChooseTitle to "Send Email"
set ChoosePrompt to “Click on Email recipient(s)
Add address with COMMAND-click”

–create choiceList which will include “Do Not Send”, “Other eMail Address”, two group names and full names of all addressees
set (first item of ChoiceList) to “Do Not Send” as string
copy “Other Email Address” to end of ChoiceList
copy “Sample to TBP Group” to end of ChoiceList
copy “Equipment to TBP Group” to end of ChoiceList

–repeat with J from 5 to (addresseeListCount + 3)

repeat with J from 5 to (addresseeListCount - 3)
–set k to J - 4
set k to J + 1
set choiceK to text item 3 of (item k of theLines) as string
copy choiceK to end of ChoiceList
end repeat

set EmaileesChosenList to dialogchoiceList(ChooseTitle, ChoosePrompt, ChoiceList)
–Item 1 of EmaileesChosenList is a LIST of addressee long names

Are you doing this from Terminal or your .bash_profile? If so, this is not going to work as it only effects processes created from your Terminal session. Mac applications do not share your Terminal environment variables.

To get the effect you desire, you are going to have to use launchd/launchctl to set your environment variable for all processes it launches on your behalf. The way this is done seems to change with each Mac OS X release, including El Capitan. The best reference I can find is this.

You can enter this command in Terminal to define OSA_LIBRARY_PATH for the duration of your login session (make sure you quit and re-launch Script Debugger):

launchctl setenv OSA_LIBRARY_PATH "/Users/bcrow/APPLESCRIPT/SCANGLOGAL2/Script Libraries"

You can also consult the launchd man page on your system.

The Apple Documentation on this issue is hopelessly out of date.

EDIT:

I should add that you can check for the presence of your environment variable in Script Debugger (or the Script Editor) like this:

do shell script "printenv OSA_LIBRARY_PATH"

Thanks for your suggestion.

Based on a tip from “MortimerGoro” at StackOverFlow, I included your suggested launchctl command in the following environment.plist file in ~\Library\LaunchAgents and, after a restart, was able to invoke library handlers in my custom location in a permanent manner.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>my.startup</string>
  <key>ProgramArguments</key>
  <array>
    <string>sh</string>
    <string>-c</string>
    <string>
    launchctl setenv OSA_LIBRARY_PATH "/Users/bcrow/APPLESCRIPT/SCANGLOBAL2/Script Libraries"
    </string>

  </array>
  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

Well, my plist file did not make it. Apparently the forum tried to parse the XML.

It’s a good trick,though, and I’d attach the file if I could figure out how to do it.

I’ve corrected your post. Just wrap your xml in

```xml
<your xml goes here/>
```

Thanks for getting that plist file displayed. I’ll make a note of the XML insertion technique.

We can consider this one solved.

do shell script "printenv OSA_LIBRARY_PATH"

–The command exited with a non-zero status.

That command doesn’t seem to work here.

(What I’m trying to do is get a list of all the places appleScript will look for libraries, I’m not trying to make appleScript look in specific places.)

Ed,

Below is what Chris Page posted on AS-users in January…

Starting in 10.11.3 the new script-library search-domain order is:

  1. The bundle of the script that references the library.
  2. The bundle of the application process that is running the script that references the library.
  3. The OSA_LIBRARY_PATH environment variable.
  4. The user domain: ~/Library
  5. The local domain: /Library
  6. The network domain: /Network/Library
  7. The system domain: /System/Library
  8. Application bundles: ./Contents/Library

Please use the environment.plist as described in my posts. No commands are going to persist through a restart.

You are getting a non-0 exit status because the OSA_LIBRARY_PATH environment variable is not defined. If you want to see which variables are defined, you can issue the printenv command without any parameters:

Same as in [Script Libraries] (https://developer.apple.com/library/mac/documentation/AppleScript/Conceptual/AppleScriptLangGuide/conceptual/ASLR_script_objects.html#//apple_ref/doc/uid/TP40000983-CH207-SW6) in the AppleScript Language Guide

Actually, I think I’m getting the non-zero result because I’m on Yosemite, not El Capitan. (I think that’s explaining several issues here).

Thanks everyone!

The printenv command has been part of Unix since before the earth cooled. I don’t think OS version is the issue in this instance.

But OSA_LIBRARY_PATH is relatively new, right? Just introduced in El Capitan?

Yes. Setting/printing OSA_LIBRARY_PATH will work the same on both OS versions. The difference will be AppleScript only honouring the variable on 10.11.

But I have to say that one should only need to use OSA_LIBRARY_PATH in exceptional circumstances. Library embedding should handle the vast majority of situations.

But I have to say that one should only need to use OSA_LIBRARY_PATH in exceptional circumstances. Library embedding should handle the vast majority of situations.

Got it.

My goal here is to run a script that will display a list of all the libraries AppleScript would see at runtime. The Script would run in SD, and the user (script writer) would be able to select which scripts to use in the current script, and use statements for those would be added in the script, and, if the script is an applet, it would store them in the proper location.

If the printenv returns a non-zero value, then I don’t have to worry about looking any further, right? if it returns a path or paths then I’ll look there.

The one aspect that I have left to deal with is how libraries distributed in script applications bundles are accessed. Do those applets with libraries have to be stored in the same folders as regular libraries for AppleScript to see them?

Ignore OSA_LIBRARY_PATH. It was added essentially for people writing script editors, as a way of designating a directory where they can safely write temporary library files. It’s not for general use.

IMO, that’s generally the wrong way to go about it.

I reckon you’re better off leaving the libraries in ~/Library/Script Libraries until you’re ready to deploy a script. You can easily add code to use them with SD’s existing tools: type “use” and Esc or F5, or write a simple clipping or text substitution. That’s going to save you a time-consuming search, and other mucking around.

When you wish to deploy outside the development Mac and you want them embedded, use a script based on the one here: http://latenightsw.com/deploying-libraries/ . That will add the libraries to the bundle, export a run-only version for deployment, and then remove them.

Let me go a step further: because some future script editor might rely on it, and because if it does so the workaround outlined here will no longer work, I’d recommend @wildcatherder see if he can’t achieve what he wants without using OSA_LIBRARY_PATH.

1 Like