【问题标题】:How to catch error when setting launchpath in NSTask在 NSTask 中设置启动路径时如何捕获错误
【发布时间】:2015-12-22 16:49:18
【问题描述】:

我正在尝试在 mac (10.10) 上使用 swift 2 运行命令行工具:

let task = NSTask()
task.launchPath = "/path/to/wrong/binary"
task.launch()

// NSPipe() stuff to catch output

task.waitUntilExit()

// never reached
if (task.terminationStatus != 0){
    NSLog("uh oh")
}

由于路径错误,我的程序以launch path not accessible 终止。但是,我不知道如何捕获此错误。在task.launch() 周围使用do { try } catch {} 不起作用,因为它不会抛出异常,查看terminationStatus 也不起作用,因为它永远不会到达。

我怎样才能发现错误的launchPath

Apple Swift 版本 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81) 目标:x86_64-apple-darwin14.5.0

【问题讨论】:

  • 您可以在运行之前尝试检查启动路径中的文件是否存在。

标签: swift swift2 command-line-interface


【解决方案1】:

在 Mac OS X High Sierra 中,launch() 已弃用。 你可以改用run()

let process = Process()
// ...

do {
    process.run()
} catch let error as NSError {
    print(error.localizedDescription)
    // ...
}

也可以看看Apple Dev Docs

【讨论】:

    【解决方案2】:

    不幸的是,没有机会捕获运行时异常。使用 try / catch 您可以从错误中恢复,而不是从运行时异常中恢复。您可以创建自己的异常处理程序,但您仍然无法从中恢复。尝试从 NSTask 中获取一些以命令为参数的常见 shell,然后使用管道将操作系统错误返回给您自己的代码。

    import Foundation
    
    let task = Process()
    let pipe = Pipe()
    task.launchPath = "/bin/bash"
    task.arguments = ["-c","unknown"]
    task.standardOutput = pipe
    task.launch()
    let handle = pipe.fileHandleForReading
    let data = handle.readDataToEndOfFile()
    let dataString = String(data: data, encoding: .utf8)
    print(dataString ?? "")
    

    将打印

    /bin/bash: unknown: command not found
    

    【讨论】:

      【解决方案3】:

      你不应该抓住它。您的计算机,即您运行应用程序的本地环境,被视为可靠的媒介。因此,NSTask 旨在期望您提供的任何路径都保证存在。这很好,因为人们通常使用 NSTask 来启动标准系统可执行文件(bashdiffrsync 等)。错误输入路径上的崩溃旨在帮助您轻松找到代码中的错误。如果您要启动嵌入在应用程序包中的自定义构建的二进制文件,您应该真的改用 XPC。

      如果您绝对需要使用 NSTask 来启动不可靠的路径,则在创建对象之前,您需要使用 NSFileManager 的fileExistsAtPath(_:isDirectory:) 手动验证路径并做出相应的反应。如果甚至 POSIX 权限标志都不可靠(此时,您的应用程序可能存在一些严重的安全问题;如果这是一个消费者应用程序项目,我建议您重新考虑您的设计),您还需要检查文件的 NSFilePosixPermissions属性以确保它是可执行的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-14
        • 1970-01-01
        • 2013-06-24
        • 1970-01-01
        • 2011-12-04
        • 2011-08-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多