问题描述
我的问题
我有一个名为 script.scpt 的 AppleScript 脚本文件。
这是我打算使用标记参数(也称为命名参数)的脚本的第一行:
on run given foo:fooStr
我打开终端并尝试通过键入以下内容来运行脚本:
osascript "/Users/UserName/Library/Mobile Documents/com~apple~ScriptEditor2/Documents/script.scpt" given foo:"bar"
我得到了由此产生的错误:
execution error: The foo parameter is missing for run. (-1701)
我已经尝试了我能想到的所有其他变体,用于在命令行中向脚本提供标记/命名参数,但没有成功。
我的问题
如何通过命令行将标记/命名参数传递给现有的 AppleScript 脚本文件?提前致谢。
背景
我以前使用以下行编写脚本:
on run argv
然后通过在我的脚本中根据它们在命令行上提供时的预定顺序位置获取我需要的值,以“典型”的方式做事情:
set fooStr to item 1 of argv
命令行在哪里:
osascript "/Users/UserName/Library/Mobile Documents/com~apple~ScriptEditor2/Documents/script.scpt" "bar"
解决方法
使用标准的 *nix shell 约定并自己解析参数列表中的任何选项。
简单的手卷示例:
property _syntax : "cmd [-A] [-B VALUE] [-h] [-] [ARG ...]"
on run argv
-- parse options
set opt_A to false
set opt_B to ""
considering case
repeat while argv is not {} and argv's first item begins with "-"
set flag to argv's first item
set argv to rest of argv
if flag is "-A" then
set opt_A to true
else if flag is "-B" then
set opt_B to argv's first item
set argv to rest of argv
else if flag is "-h" then
log _syntax
return
else if flag is "-" then
exit repeat
else
error "Unknown option: " & flag
end if
end repeat
end considering
-- do any validation here
doStuff(opt_A,opt_B,argv)
end run
to doStuff(foo,bar,baz)
-- do work here
end doStuff
(如果您的选项特别复杂,或者您编写了很多这样的脚本,您可能更喜欢使用现有的选项解析器,例如通过 AppleScript-ObjC 的 NSArgumentDomain
of NSUserDefaults
,或 {{ File library 中的 1}}。)
run
处理程序与常规的用户定义处理程序略有不同 - 作为 event 处理程序,它将参数作为单个列表。您可以使用带标签的参数定义它,但是当某些执行脚本时,使用命令行参数的标准 POSIX 约定。
命令行比标记参数早了几十年;它使用选项开关代替。你也可以实现类似的东西,但这是否值得取决于你想要做什么。
开关的替代方法是调用一个处理程序,在安排参数后运行目标(脚本的 run
处理程序将像往常一样声明)。一种方法是将参数记录与默认值合并,然后按所需顺序传递键列表,例如:
to runWithArgs given args:argRecord -- run shell script with arguments from merged records
set defaults to {foo:"foo",bar:"bar",baz:"baz",another:"four"} -- or whatever
if class of argRecord is not record then set argRecord to {}
set merged to {foo,baz,another} of (argRecord & defaults) -- the desired keys and order
set arguments to ""
repeat with anItem in merged
set arguments to arguments & space & quoted form of (anItem as text)
end repeat
do shell script "echo" & arguments -- osascript,etc
end runWithArgs
runWithArgs given args:{whatever:"no,not this one",another:4,foo:"this is a test"}
不使用命令行的替代方法是使用 load script
,并调用各个处理程序(您不一定需要使用 run
处理程序)。例如:
set scpt to load script "/path/to/foo.scpt"
tell scpt to run given foo:"bar"
tell scpt to someHandler given someLabel:"whatever"