多个NSTasks导致输出不一致

代码片段

我正在开发一个Swift应用程序,该程序与外部二进制文件进行交互(通过NSTask),并针对每一行将输出作为字符串数组返回。

当多次调用executeCommand函数时,命令开始无法返回​​期望的数据。

在下面的示例Playground中,我在diskutil中轮询卷名。

在调试区域中,我得到的第一个响应是:

  • 不适用(无文件系统)
  • Macintosh HD
  • 无法获取卷名
  • 无法获取卷名
  • 无法获取卷名

只需重新运行Playground即可:

  • 不适用(无文件系统)
  • 无法获取卷名<-Macintosh HD发生了什么?
  • 无法获取卷名
  • 无法获取卷名
  • 无法获取卷名

        import Cocoa
    
    func executeCommand(launchPath: String, arguments: [String], additionalDelay: Int=0) -> [String] {
    
        let outputPipe = NSPipe()
        var outputArray = [String]()
    
        let task = NSTask()
        task.launchPath = launchPath
        task.arguments = arguments
        task.standardOutput = outputPipe
    
        outputPipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
    
        NSNotificationCenter.defaultCenter().addObserverForName(NSFileHandleDataAvailableNotification, object: outputPipe.fileHandleForReading , queue: nil) {
            notification in
    
            let output = outputPipe.fileHandleForReading.availableData
            let outputString = String(data: output, encoding: NSUTF8StringEncoding) ?? ""
    
            outputArray = outputString.componentsSeparatedByCharactersInSet(.newlineCharacterSet())
    
            outputPipe.fileHandleForReading.waitForDataInBackgroundAndNotify()
    
        }
    
        task.launch()
        sleep(UInt32(additionalDelay)) // Additional delay
        task.waitUntilExit()
    
        // Remove last empty line from output array.
        if outputArray.count > 0 {
            outputArray.removeLast()
        }
    
        return outputArray
    
    }
    
    
    // Example usage
    
    
    
    // Output volume name from provided disk identifier
    func volumeName(identifier: String) -> String {
        let volumeNameCommand = "/usr/sbin/diskutil info \(identifier) | awk '/Volume Name:/' | sed 's/Volume Name://g'| sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'"
        let volumeNameOutput = executeCommand("/bin/bash", arguments: ["-c", volumeNameCommand])
    
        var volumeName = "Unable to obtain volume name"
    
        if volumeNameOutput.count > 0 {
            volumeName = volumeNameOutput[0]
        }
    
        return volumeName
    }
    
    let identifiers = ["/dev/disk0","/dev/disk1","/dev/disk2","/dev/disk3","/dev/disk4"]
    
    for identifier in identifiers {
        print(volumeName(identifier))
    }
    

我确实需要一致的结果,但不了解我要去哪里。

任何帮助将不胜感激!

代码片段

我认为任务的异步执行会导致结果不一致。下面是一个按预期工作的新功能:

func executeCommand(launchPath: String, arguments: [String]) -> [String] {

    let task: NSTask = NSTask()
    let pipe: NSPipe = NSPipe()

    task.launchPath = launchPath
    task.arguments = arguments
    task.standardOutput = pipe
    task.launch()
    task.waitUntilExit()

    let handle = pipe.fileHandleForReading
    let data = handle.readDataToEndOfFile()
    let outputString = String(data: data, encoding: NSUTF8StringEncoding) ?? ""

    var outputArray = [String]()
    outputArray = outputString.componentsSeparatedByCharactersInSet(.newlineCharacterSet())
    return outputArray

}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章