转换为一行 AppleScript

发布于 2024-10-22 02:43:21 字数 193 浏览 6 评论 0原文

我有一系列 AppleScript 命令需要在一行 AppleScript 中实现。代码如下。

delay 2
tell application "System Events" to keystroke "foo"
tell application "System Events" to keystroke return

I have a series of AppleScript commands I need to implement into a single line of AppleScript. The code is below.

delay 2
tell application "System Events" to keystroke "foo"
tell application "System Events" to keystroke return

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无法言说的痛 2024-10-29 02:43:21

您可以通过将字符串连接在一起,将两个击键命令合并为一个命令:

tell app "System Events" to keystroke "foo" & return

但这仍然留下一个命令和一个语句(delaytell ...  到...)。

实际上,AppleScript 的语句分隔符是换行符。在现代 AppleScript 中,换行符可以是 CR、LF 或 CRLF(分别是:旧 Mac、Unix 或 DOS 样式)。没有方便的方法来编写多语句行(如 C、Perl、Ruby 等中的 foo; bar; baz;)。

对于您的特定请求,您可以通过使用延迟作为表达式的一部分,以一种非常丑陋的方式将两者结合起来。

tell application "System Events" to keystroke "" & (delay 2) & "foo" & return

这很丑陋,因为延迟从技术上讲不返回任何值,但我们可以将其与空字符串连接而不会导致错误。

问题是这样的结构不是很“通用”。您可能并不总是能够以相同的方式将任何命令转换为表达式(并且您不能使用 tell 等语句作为表达式1的一部分)。为了更简洁(和混淆),您可以将最后一位写为 "foo" &返回& (延迟 2)。它仍然以相同的顺序运行(首先延迟),因为必须先计算串联表达式的每个部分,然后才能将其构建为击键命令的单个值。

<子>
1 缺少将它们放入给定运行脚本的字符串中。即使如此,某些语句(循环、try/catch 等)始终是多行的;尽管您可以通过使用转义换行符或串联以及换行符常量之一来解决这个问题(如下所示)。

您可以使用带有字符串参数的运行脚本,并使用反斜杠2转义来表示换行符。

run script "delay 0.1\ntell app \"System Events\" to keystroke \"foo\" & return"

AppleScript 编辑器可能会将转义符号转换为文字,除非您在其编辑首选项中启用了“转义制表符和字符串中的换行符”(在 10.5 及更高版本中提供)。您始终可以使用return常量和连接来代替字符串内/转义符号。

run script "delay 0.1" & return & "tell app \"System Events\" to keystroke \"foo\" & return"

<子>
2 如果您要在 Objective C 字符串文字中表示此类字符串(正如您的评论之一可能暗示的那样),那么您将必须转义 Objective C 的反斜杠和双引号(... &“告诉应用程序\\\”系统...)。

或者,如果您最终尝试使用 osascript 运行代码,那么您可以利用 -e 的每个实例将成为单独的行来将所有内容放在一个 shell 命令行上。

osascript -e 'delay 2' -e 'tell app "System Events" to keystroke "foo" & return'

You can combine the two keystroke commands into a single one by concatenating your strings together:

tell app "System Events" to keystroke "foo" & return

But that still leaves you with one command and a statement (delay and tell … to …).

Effectively, AppleScript’s statement separator is a line break. In modern AppleScript the line breaks can be either CR, LF, or CRLF (respectively: old-Mac-, Unix-, or DOS-style). There is no convenient way write a multi-statement line (like foo; bar; baz; in C, Perl, Ruby, et cetera).

For your specific request, you can combine the two in a really ugly way by using delay as a part of an expression.

tell application "System Events" to keystroke "" & (delay 2) & "foo" & return

This is ugly because delay technically returns no value, but we are able to concatenate it with an empty string without causing an error.

The problem is that such a construction is not very “general purpose”. You may not always be able to turn any command into an expression in the same way (and you can not use statements like tell as a part of an expression1). For a bit more brevity (and obfuscation), you can write the last bit as "foo" & return & (delay 2). It still runs in the same order (delay first) because each part of the concatenation expression must be evaluated before it can be built into a single value for the keystroke command.


1 Short of putting them in a string given to run script that is. Even then, some statements (loops, try/catch, etc.) are always multi-line; though you can get around that by using escaped line breaks or concatenation and one of the line break constants (as follows).

You could use run script with a string argument and use the backslash2 escapes to represent the line breaks.

run script "delay 0.1\ntell app \"System Events\" to keystroke \"foo\" & return"

AppleScript Editor may translate the escape notation into a literal unless you have “Escape tabs and line break in string” enabled in its Editing preferences (available in 10.5 and later). You could always use the return constant and concatenation instead of the in-string-literal/escape-notation.

run script "delay 0.1" & return & "tell app \"System Events\" to keystroke \"foo\" & return"


2 If you are going to represent such strings inside an Objective C string literal (as one of your comments might imply), then you will have to escape the backslashes and double quotes for Objective C, also (…& \"tell app \\\"System…).

Or, if you are ultimately trying to run the code with osascript, then you can use the fact that each instance of -e will become a separate line to put it all on a single shell command line.

osascript -e 'delay 2' -e 'tell app "System Events" to keystroke "foo" & return'
初懵 2024-10-29 02:43:21

osascript -e 'line1' -e 'line2' ...

osascript 的联机帮助页建议使用多个 -e 来构建多行脚本:

-e 语句
输入脚本的一行。如果给出 -e,osascript 将不会在参数列表中查找文件名。
可以给出多个 -e 选项来构建多行脚本。
因为大多数脚本都使用字符
对于许多 shell 程序来说是特殊的(例如,AppleScript 使用单引号和双引号,“(”,
“)”和“*”),该语句必须被正确引用并转义,才能完好无损地通过 shell。

克里斯·约翰森已经给出了答案,但包含在一个较长的答案中,因此可以忽略。

osascript -e 'line1' -e 'line2' …

The manpage for osascript suggests to use several -e to build up a multi-line script:

-e statement
Enter one line of a script. If -e is given, osascript will not look for a filename in the argument list.
Multiple -e options may be given to build up a multi-line script.
Because most scripts use characters
that are special to many shell programs (for example, AppleScript uses single and double quote marks, “(”,
“)”, and “*”), the statement will have to be correctly quoted and escaped to get it past the shell intact.

Answer already given by Chris Johnsen, but is contained in a longer answer and therefore can be overlooked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文