我使用 JXA 为 Alfred 2 编写工作流程脚本,最近尝试从另一个脚本中运行一个脚本。我需要在脚本之间传递一些文本,因此我决定使用参数,但每当我尝试传递字符串、数字、数组或任何其他不是对象的东西时,它都会给出错误“
Error on line 4: Error: An error occurred.
”
”。如果我传递一个对象,第二个脚本(由第一个脚本运行的脚本)会收到一个空对象,而不是传递给它的对象。当第一个脚本是 AppleScript 时,也会发生同样的情况,但如果第二个脚本是 AppleScript,则一切都可以正常工作。从命令行通过 osascript
传递参数也可以。 API 是否损坏或者我做错了什么?
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.runScript(new Path("/path/to/second/script.scpt"), { withParameters: "Hello World!" });
function run(args) {
return args;
}
如果按如下方式编辑第二个脚本,则会显示对话框,但第一个脚本的
runScript
方法仍然返回错误。
function run(args) {
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.displayDialog(args.toString());
return args;
}
除了参数问题之外,
runScript
功能实际上似乎运行良好。该错误实际上并没有被抛出,只是由脚本编辑器显示,并且在调用 runScript
后继续执行,就好像什么也没发生一样。尽管参数不起作用,但返回的值也完美工作。
要在 Alfred 2 中运行某些代码(由搜索、键盘命令等触发),必须将其输入到应用程序的框中,而不是文件中。
输入代码的框非常小,并且不提供语法突出显示,这使得编辑代码变得困难且烦人。对于较小的文件,还可以,但是对于较大的文件,使用短脚本来运行脚本文件会更容易。我尝试过 Bash,这将是最简单的选项,但 Alfred 2 没有提供转义单引号的选项。我也无法使用脚本库(据我所知,如果我错了,请纠正我),因为代码不在脚本包中,并且所有必需的文件都需要位于同一文件夹中(出于导出原因)。
我不知道如何避免
runScript
错误,但我可以建议另一种方法:将脚本加载为脚本库。
将脚本转换为库就像将脚本保存到
~/Library/Script Libraries
一样简单。如果您的脚本文件名为 script.scpt
并且有一个运行处理程序,并且您将其保存到 Script Libraries
文件夹,那么您可以从另一个脚本调用它,如下所示:
Library("script").run(["Hello, world!"])
脚本库记录在 OS X 10.10 的 JXA 发行说明、介绍 JXA 的 WWDC 2014 会议视频以及 AppleScript 语言指南中。
根据脚本库的 AppleScript 语言指南文档,有一个用于查找
Script Libraries
文件夹的搜索策略。它搜索的第一个地方是:
如果引用库的脚本是包,则脚本的包资源目录。这意味着脚本可以与它们使用的库一起打包和分发。
要将其应用于问题中给出的示例,您需要将第一个脚本重新保存为脚本包,然后将第二个脚本嵌入到第一个脚本中。
例如,如果您将第一个脚本重新保存为
script.scptd
,那么您可以将第二个脚本 embedded.scpt
保存为 script.scptd/Resources/Script Libraries/embedded.scpt
。 然后您应该能够使用 Library('embedded')
访问脚本库。
要将现有脚本重新保存为脚本包,您可以使用脚本编辑器中的
File > Export...
菜单项,也可以在按住 option 的同时选择 File
菜单以显示 File > Save As...
菜单项。通过 File Format
弹出菜单,您可以选择 Script bundle
格式。
打开脚本包后,您可以使用
Show Bundle Contents
菜单项或工具栏按钮显示包内容面板。然后,您可以使用齿轮菜单在 Script Libraries
文件夹内创建 Resources
文件夹,然后可以将脚本拖到该文件夹中。
以下内容也适用,仅适用于 JXA(加上 osascript 到 stderr 的一些输出):
在目录 ~/Library/Script\ Libraries 中: 文件调用Script-jxa.sh:
#! /usr/bin/env osascript -l JavaScript
const app = Application.currentApplication()
app.includeStandardAdditions = true;
const path =
Path("/Users/jonathan/Library/Script\ Libraries/calledScript-jxa.scpt")
app.runScript(path, {withParameters: "The message was received."})
文件名为Script-jxa.scpt: // 通过脚本库调用由另一个脚本运行的简单脚本
function run(msg){
const app = Application.currentApplication()
app.includeStandardAdditions = true;
const se = Application('System Events');
app.activate()
app.displayDialog(msg)
}
终端:
$ cd ~/Library/Script\ Libraries
$ chmod 755 callingScript-jxa.sh
$ callingScript-jxa.sh
2025-01-10 12:26:06.564 osascript[12091:3161373] +[IMKClient subclass]: chose IMKClient_Modern
2025-01-10 12:26:06.564 osascript[12091:3161373] +[IMKInputSession subclass]: chose IMKInputSession_Modern