3

我正在尝试使用 AppleScriptObjC 作为包装器来自动化三个或四个 bash shell 脚本。这将给我一个友好的 gui 前端来选择数据文件等,以及方便的文本文件操作和几个 bash 脚本的处理。

一切正常(我可以按我的按钮并运行 shell 脚本),除了我不知道如何使事情变得半便携。我想要一个可以分发给其他人的应用程序或包,所需的脚本文件以某种方式由应用程序合并或生成,而不是暴露给用户。

我是 Xcode 和 AppleScriptObjC (ASOC) 的菜鸟,我看不到这样做的方法。- 我可以将脚本作为一组简单的 do shell 脚本命令运行,或者通过发送到终端窗口的命令来运行,但这意味着必须分发所有单独的 shell 文件并将其作为一堆片段放在正确的位置。- 我尝试从 ASOC 中生成脚本文件,但由于 ASOC 处理字符串和特殊字符的方式,我遇到了构建文件的障碍。我已经尝试过普通字符串或字符串构造的引号形式。作为背景,Apple Technical Note TN2065是相关的。以这种方式创建文件会丢失特殊字符。这段代码演示了这个问题(例如,我做错了什么!):

set scriptName to "/Users/me/Desktop/myScript.sh" -- Name of file
-- Define a multi line string:
set scriptContents to "       First Line - OK  
Second Line, all good so far
$Test fails - the (dollar sign)Test vanishes
\"$Test\" also fails
Last line"
do shell script ("cd " & myFolder & "; echo \" " & scriptContents & " \" > " & scriptName)

如果无法从 ASOC 中创建所需的 shell 脚本或访问作为支持文件包含在应用程序包中的脚本,我将做很多从 bash 到 AppleScriptObjC 的棘手移植!

建议或解决方案将不胜感激:1.如何使用AppleScriptObjC编写任意多行文件,包括控制字符等。2.或3.如何打包shell脚本以便ASOC可以在需要时运行它?

4

3 回答 3

4

经过几个小时的研究和实验,回答了我自己的问题(感谢 macscripter.net 和 autodidaktos.com 上的各种帖子):

  1. 通过菜单 File - Add Files to (yourProject)... 将脚本文件(例如 yourScriptFile.sh)添加到项目中...

  2. 在应用程序包中包含脚本文件,以便在分发时将其包含在应用程序中:

    • 在 Project Navigator 或 Jump Bar 中选择您的项目
    • 选择“构建阶段”选项卡
    • 展开“复制捆绑资源”部分(这适用于 Xcode 4.6.3,可能与其他版本不同)
    • 通过单击列表底部的“+”按钮将项目添加到捆绑资源
    • 选择要添加到包中的脚本文件,例如 yourScriptFile.sh
  3. 在您的 AppleScriptObjC 脚本中,添加以下子例程

    on applicationWillFinishLaunching_(aNotification)
        set pathToResources to (current application's class "NSBundle"'s mainBundle()'s resourcePath()) as string
    end applicationWillFinishLaunching_
    
  4. 同样在您的 AppleScriptObjC 脚本中,在适当的地方添加以下内容:

    property pathToResources : "NSString"  -- works if added before script command
    
  5. 在适当的情况下,还在您的 AppleScriptObjC 脚本中添加以下内容:

    set yourScript to pathToResources & "/yourScriptFile.sh" 
    -- gives the complete unix path
    -- if needed, you can convert this to the Apple style path:
    set yourScriptPath to (((yourScript as text) as POSIX file) as alias)`
    
  6. 顺便说一句,您可以使用打开文件进行读取

    tell application "Finder"
        open yourScriptPath
    end tell
    

然后应该可以执行脚本或将其复制到某个地方以供用户使用do shell script构造访问。如果合适的话,也应该可以直接从包中执行脚本。

于 2013-08-27T17:43:18.080 回答
0

这考虑了以下事实:

firstScript = 指向名为 scriptNumberOne.sh 的脚本的变量名称
scriptNumberOne.sh = 我嵌入到我的应用程序中运行的脚本
ButtonHandlerRunScript_ = Xcode中接收到的操作的名称
pathToResources = 指向我的内部资源文件夹的变量应用程序,无论其当前位置如何

AppDelegate.applescript使用此信息,下面是我的 AppleScriptObjC Xcode 项目中的香草副本:

script AppDelegate
property parent : class "NSObject"
property pathToResources : "NSString"

on applicationWillFinishLaunching_(aNotification)
    set pathToResources to (current application's class "NSBundle"'s mainBundle()'s resourcePath()) as string
end applicationWillFinishLaunching_

on ButtonHandlerRunScript_(sender)
    set firstScript to pathToResources & "/scriptNumberOne.sh"
    do shell script firstScript
end ButtonHandlerRunScript_

on applicationShouldTerminate_(sender)
    -- Insert code here to do any housekeeping before your application quits 
    return current application's NSTerminateNow
end applicationShouldTerminate_

end script
于 2013-11-04T13:23:17.603 回答
0

也许对于 shell 脚本来说是不同的,但是对于 perl 脚本,你可以用更少的步骤来做到这一点。

刚才做了如下,在XCode 6中(在5中也是一样):

  1. 添加脚本文件:File > Add files to [your-project-name]

  2. 只需通过以下方式在任何需要的地方引用文件:

    (path to resource "myAwesomeScript.pl")

而已!

现在,正如您所料,它返回一个 Finder 样式路径,所以当然您必须执行通常的“引用形式的 POSIX 路径的”杂技以获得 UNIX 路径并转义引号和空格,但这一切都按照通常..

作为参考,这是我最终得到的实际处理程序。只更改了函数和脚本名称以保护无辜者;)

on doCoolStuffWithLogsFrom(theThingName)
    set theLogsFolder to POSIX path of ((path to home folder as string) & "Library:Logs:Something:Something:" & theThingName)
    tell me to log "Processing logs in: " & theLogsFolder
    do shell script "/usr/bin/perl " & (quoted form of POSIX path of (path to resource "doCoolStuffWithLogs.pl")) & " " & quoted form of theLogsFolder

end doCoolStuffWithLogsFrom

几件小事让我大吃一惊:

  • 不要忘记在 .pl 和脚本参数 ( & " " &)之间添加空格

  • 最后一个“引用形式”是控制台日志行输出未转义的 UNIX 路径的位置。只是我的偏好,为了可读性。您可能更喜欢另一种方式,即将引用形式的 'set theLogsFolder' 行,以便日志输出很容易复制/粘贴到终端命令中。

于 2014-08-05T20:21:08.500 回答