我正在Xcode 9中编写一个基于swift的macOS应用程序,用于我的计算机(非分布式)。我在/usr/local/bin中安装了EXIFtool(独立于应用程序),可以从终端应用程序成功使用它。我正在尝试从我的应用程序访问EXIFtool。
我的应用程序有一个按钮,单击该按钮时应通过执行此脚本运行EXIFtool命令。
@IBAction func arrowClicked(_ sender: Any) {
arrow.isEnabled = false
let task = Process.launchedProcess(launchPath: "/usr/local/bin/exiftool", arguments: [rawURL])
task.waitUntilExit()
arrow.isEnabled = true
}
脚本失败,出现"启动路径不可访问"错误。我输入什么作为参数并不重要(在上面的片段中,rawURL是一个字符串,包含用户识别的图像文件的路径
我在这里找到的类似问题的答案集中在路径的格式上(例如,必须是完整的路径,以/开头等)。我的启动路径来自终端对"哪个exiftool"的响应,所以我认为这是正确的。
UPDATE:我遵循Matt提供的链接,并重写代码以使用shell脚本。我使脚本可执行,并成功地通过Terminal和TextWrangler运行它。但是在Xcode中访问它会导致一条"不允许操作"的消息。
关闭应用程序沙盒可以解决原始的"启动路径不可访问"消息和修改后的尝试的"不允许操作"消息。
不幸的是,一个二进制文件可能无法在沙盒环境中运行,而另一个二进制程序可能运行得很好,原因有很多。
在您的案例中,您可以禁用沙箱,因此这是一个简单(明智)的解决方案,但对于任何没有这种奢侈的人来说,下面是一些记录一些相关因素的信息。
这里有一个问题,问为什么/sbin/ping
运行良好,而/usr/sbin/traceroute
却不正常。
从其中一个答案来看:
ping
与traceroute
-前者是非特权程序,后者是特权程序并作为根运行
您可以看到他们权限的差异:
$ ls /sbin/ping
-r-xr-xr-x 1 root wheel 41K 30 May 11:36 /sbin/ping
$ ls /usr/sbin/traceroute
-r-sr-xr-x 1 root wheel 37K 30 May 11:36 /usr/sbin/traceroute
跟踪路由上的s
意味着它将作为root
执行,这在沙盒环境中自然是不允许的。以下内容可能会有所帮助,来自https://coderanch.com/t/110770/os/permissions-meaning#558594:
对于文件,"s"的意思是"setuid-exec"。如果文件具有s权限,则它是可执行的,此外,进程的用户id和/或组id设置为文件所有者的用户或组id,这取决于设置的是用户还是组"s"。这是一种给用户有限的root权限的方法——一个普通用户执行时以root身份运行的程序
下面的苹果技术问答超出了我的理解范围,但也可能与此相关;一个名为"常见应用程序沙盒问题"的QA1773,讨论二进制文件是否是Mach-O可执行文件:
您可以使用file命令检查二进制文件是否是Mach-O可执行文件。如果二进制文件的任何部分将自己标识为Mach-O可执行文件或Mach-O 64位可执行文件,则必须对二进制文件进行沙盒处理。
对于ping
,它看起来像:
$ file /sbin/ping
/sbin/ping: Mach-O 64-bit executable x86_64
我的看法是,如果二进制文件是Mach-O executable
,并且你想从沙盒应用程序中运行它,那么你必须:
- 自己从源代码编译二进制文件,赋予它适当的权限,或者
- 将代码导入你的应用程序,并将其直接编译到应用程序中