Swift 4 launchedProcess启动路径不可访问



我正在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却不正常。

从其中一个答案来看:

pingtraceroute-前者是非特权程序,后者是特权程序并作为根运行

您可以看到他们权限的差异:

$ 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,并且你想从沙盒应用程序中运行它,那么你必须:

  • 自己从源代码编译二进制文件,赋予它适当的权限,或者
  • 将代码导入你的应用程序,并将其直接编译到应用程序中

最新更新