使用 Automator.app 和 Platypus.app,我已经成功将一个用于在 MacBook Pro 上执行 Wi-Fi 电源循环的简单 shell 脚本打包成了两个应用程序。这两个应用程序都可以正常运行,但是有一个明显的问题需要纠正:这些应用程序引用了程序外部的 shell 脚本。如何将 shell 脚本嵌入应用程序资源中,并引用它,以便即使原始源文件被移动,应用程序也能正常运行?
使用 Automator.app 和 Platypus.app,我已经成功将一个用于在 MacBook Pro 上执行 Wi-Fi 电源循环的简单 shell 脚本打包成了两个应用程序。这两个应用程序都可以正常运行,但是有一个明显的问题需要纠正:这些应用程序引用了程序外部的 shell 脚本。如何将 shell 脚本嵌入应用程序资源中,并引用它,以便即使原始源文件被移动,应用程序也能正常运行?
只是提一下,如果您在脚本上获取信息,您可以将其设置为使用终端打开。这将在双击脚本时运行它。
否则,将脚本打包成 .app 包非常简单。Mac OS X 将愉快地运行标识为应用程序可执行文件的任何脚本。
至少,您需要放置以下结构:
其中名为(名称)的文件是您的脚本(必须可执行,并且必须有 shebang 行)。(名称) 必须在 .app 目录和脚本文件中相同:例如,如果您的应用程序目录名为“我的 Shell 脚本.app”,那么 MacOS 目录中的文件必须被称为“我的 Shell 脚本”,没有扩展名。
如果这不方便,可以使用 Info.plist 文件来指定替代可执行文件名。Info.plist 放在 Contents 目录中:
如果您在属性列表中将 MyScript 指定为 CFBundleExecutable
,则此结构(Wrapper.app 中的 MyScript 可执行文件)有效:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>MyScript</string>
</dict>
</plist>
使用 Info.plist 文件可能更好,因为这样可以在不破坏它的情况下重命名包装器。
以下是一个示例脚本,它使用 /bin/sh
作为解释器,但你实际上可以使用任何东西 (#!/usr/bin/swift
, #!/usr/bin/python
等等)。
#!/bin/sh
open -a Calculator
双击应用捆绑包即可运行脚本。
您可以在 Contents
目录中打包其他所需内容。如果感觉有余力,可以通过添加 Resources
目录等内容来重现标准可执行捆绑包布局。
虽然这样可以工作,但似乎没有办法从脚本中访问Contents目录。它没有通过环境变量传递给bash,也没有其他地方可以找到。这使得将东西捆绑到Contents目录中变得困难,因为似乎无法通过bash脚本访问它。网络上有各种各样的黑客技巧,但它们都涉及有效地按名称搜索脚本,这意味着如果应用程序的两个版本在两个位置,则会失败。 有人解决了这个问题吗?
$(cd "$(dirname "$0")"; pwd)
让它正常工作了。 - Andreas Riedmüller