【问题标题】:How can I launch an AppleScript application and run shell scripts from another AppleScript?如何启动 AppleScript 应用程序并从另一个 AppleScript 运行 shell 脚本?
【发布时间】:2014-03-27 16:23:41
【问题描述】:

这是我的文件:

launcher.applescript

tell application ":path:to:applescript:apps:shell-script-launcher.app" to launch

shell-script-launcher.app [AppleScript,另存为应用程序]

 do shell script "say starting script"

期望的行为:

  1. 从 AppleScript 编辑器运行“launcher.applescript”
  2. 监听“启动脚本”

实际行为:

  1. 通过在查找器中手动打开“shell-script-launcher.app”来运行它会产生预期的行为
  2. 运行“launcher.applescript”会打开“shell-script-launcher.app”,但它从不执行 shell 脚本。

我尝试将应用保存为“仅运行”和“保持打开”。仍然没有进展。你有什么建议吗。最终结果必须是 Application 而不是 Applescript。

【问题讨论】:

  • 因此将 launcher.applescript 更改为“激活”而不是“启动”会触发所需的行为。但现在它运行了两次。谁能帮我解决这个问题?
  • 你的 OSX 版本是什么?

标签: macos shell applescript


【解决方案1】:

概念上

  • run 命令启动并运行应用程序隐藏
  • activate 命令启动、运行并激活应用程序(使其成为最前面的应用程序)
  • launch, according to Apple, "启动应用程序,如果它尚未运行,但不发送运行命令。"
    • 对于基于 AppleScript 的应用程序,这应该意味着它们已加载,但未执行(即,它们的 - 隐式或显式 - on run 处理程序未被调用),但在实践中,直到 10.9 - 见下文。
    • 不清楚(对我而言)这对于基于 -AppleScript 的应用程序究竟意味着什么

以下是 Apple thinks it works with AppleScript-based applications 的说明,只有从 OSX 10.10 (Yosemite) 开始才是正确的

脚本可以向脚本应用程序发送命令,就像它可以向其他应用程序发送命令一样。要启动非保持打开的应用程序并运行其脚本,请使用启动命令后跟运行命令,如下所示:

launch application "NonStayOpen"
run application "NonStayOpen"

启动命令启动脚本应用程序,而不向其发送隐式运行命令。当运行命令被发送到脚本应用程序时,它会处理该命令,必要时发回回复,然后退出。

在 OSX 10.8、10.9 上出现问题(在 OSX 10.10 中已修复):

launch 本身足以运行应用程序,并且确实是唯一适用于基于 AppleScript 的应用程序的命令。 任何执行 runactivate 的尝试(无论是否除了 launch)都会运行应用程序 - 从 AppleScript 编辑器运行时甚至 两次(!;只使用一次 osascript) - 但报告失败<appName> got an error: Connection is invalid

这让我觉得 错误
不确定 OSX 版本

注意:我曾经目睹过 launch 的非执行行为,但是我在 OS X 10.9.2 和 OS X 10.8.5 上从头开始创建的每个非保持打开的基于 AppleScript 的测试应用程序还执行带有launch 的脚本 - 与文档所说的相矛盾。

如果您的系统表现不同和/或旧版本的表现如何,请告诉我。没有使用launch 创建的应用程序是在哪个 OSX 版本上创建的?

OSX 10.10 上,行为与文档一致,有一点值得注意:

  • 如果意图是一步启动并运行,run application 就足够了 - 首先不需要单独的launch application 命令。

选项


  • @user309603 的 实用解决方案 只需使用 do shell script 和标准 open 实用程序 即可绕过问题 - 无论应用程序是否为 AppleScript,这都应该有效 -基于与否:
do shell script "open " & ¬
    quoted form of POSIX path of ¬
    alias ":path:to:applescript:apps:shell-script-launcher.app"

  • 如果您知道您正在调用的应用程序的类型

    • 运行 基于 AppleScript 的应用程序:最好使用 run script file,正如 @regulus6633 所建议的那样 - 这具有额外的优势,即被调用的基于 AppleScript 的应用程序可以将对象直接返回给调用者:
run script file ":path:to:applescript:apps:shell-script-launcher.app"

注意:还有load script file,它确实让您只需加载脚本代码,而无需立即执行。

  • 运行非AppleScript应用:使用run/activate隐藏/最前面运行应用:
run application ":path:to:applescript:apps:shell-script-launcher.app"

  • 您可以使用run,即使是基于 AppleScript 的应用程序,也可以简单地忽略错误 使用try ... end try,正如@atonus 所建议的那样 - 缺点是你赢了'无法检测到调用应用程序的实际失败。

您可以通过选择性地仅忽略特定的 Connection invalid 错误(假设此错误不会合法发生)[在 OSX 10.10 上不再需要] 来缓解这种情况:

try
    run application "Macintosh HD:Applications:_Sandbox-AppleScript0.app"
on error number -609 # 'Connection is invalid' error that is spuriously reported
    # simply ignore
end try

  • 最后,在 OSX 简单地使用 launch 命令(尽管这对 OP 不起作用,可能是因为在
 launch application ":path:to:applescript:apps:shell-script-launcher.app"

但是,出于两个原因,不建议这样做

  • 在 OSX 10.10 中,Apple 已将 launch 行为修复为不再执行,因此您的代码在此处运行时会中断。
  • 虽然非 AppleScript 应用程序在使用 launch 调用时通常会运行(隐藏),但 documentation says AppleScript“不会向其发送运行命令”并且“允许您打开应用程序而不执行其通常的启动过程,例如打开一个新窗口”——具体含义尚不清楚,不同的应用程序似乎处理方式不同。

【讨论】:

    【解决方案2】:

    Applescript 有“运行脚本”命令。它适用于 applescripts 或 applescript 应用程序。因此,如果我的桌面上有您的应用程序,那么它就可以工作...

    set appPath to (path to desktop as text) & "shell-script-launcher.app"
    run script file appPath
    

    【讨论】:

    • +1 告诉我们run script file,这是调用外部 AppleScript 代码的最佳方式(尽管听起来 OP 最终可能不会调用基于 AppleScript 的应用程序)。跨度>
    【解决方案3】:

    你试过open吗?

    do shell script "open 'path/to/applescript/apps/shell-script-launcher.app' && say starting script"
    

    【讨论】:

      【解决方案4】:

      把它放在“try”关键字之间。

      try
      tell application ":path:to:applescript:apps:shell-script-launcher.app" to activate
      end try
      

      【讨论】:

      • 这行得通,但如果盲目地忽略错误,您可能会错过真正的错误。
      【解决方案5】:

      将您的脚本保存为应用程序。 将所需的脚本添加到 Script 文件夹中(参见下面的路径)

      按如下方式运行,根据您要运行的脚本类型更改...

      property theApplicationPath : the path to me as text <br/>
      property theShellScriptPath : theApplicationPath & "Contents:Resources:Scripts:test.command"<br/>
      property theShellScript : the quoted form of POSIX path of theShellScriptPath<br/>
      <br/>
      tell application "Terminal" to (do shell script "/bin/bash " & theShellScript)
      <br/>
      

      Boom,鲍勃是你的叔叔!至少对我来说。

      【讨论】:

      • 这正是我所看到的,谢谢!使用它,我可以从 main.scpt 文件中加载我放置在应用程序的 Scripts 文件夹中的 bash 脚本
      【解决方案6】:

      很简单,用普通的do shell script,例如:

      do shell script "open " & ¬
          quoted form of POSIX path of ¬
          alias ":path:to:applescript:apps:shell-script-launcher.app"
      

      【讨论】:

        【解决方案7】:

        这可能会有所帮助,但我不是这方面的专家。在这种情况下,我发现双重启动行为(在 Yosemite 上,我没有使用任何其他版本的 OS X)非常烦人,我发现可以检查它是否已经在运行。

        这个脚本让我可以随时启动一个新终端。

        if application "Terminal" is running then
            tell application "Terminal"
                activate
                do script ""
            end tell
        else
            tell application "Terminal" to activate
        end if
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-23
          • 2012-07-02
          • 1970-01-01
          • 2012-08-08
          • 1970-01-01
          相关资源
          最近更新 更多