加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 如果存在管道,则通过NSTask终止cURL

发布时间:2020-12-14 05:46:41 所属栏目:百科 来源:网络整理
导读:我试图在Swift中为一个简单的命令行批处理脚本同步读取URL的内容.为了简单起见,我使用cURL – 我知道如果必须的话,我可以使用NSURLSession.我也在使用OSX上的Swift开源版本进行swift构建. 问题是,在某些URL上,如果stdout已重定向到管道,则NSTask永远不会终止
我试图在Swift中为一个简单的命令行批处理脚本同步读取URL的内容.为了简单起见,我使用cURL – 我知道如果必须的话,我可以使用NSURLSession.我也在使用OSX上的Swift开源版本进行swift构建.

问题是,在某些URL上,如果stdout已重定向到管道,则NSTask永远不会终止.

// This will hang,and when terminated with Ctrl-C reports "(23) Failed writing body"
import Foundation
let task = NSTask()
let pipe = NSPipe()
task.launchPath = "/usr/bin/curl"
task.arguments = ["http://trove.nla.gov.au/newspaper/page/21704647"]
task.standardOutput = pipe
task.launch()
task.waitUntilExit()

但是,如果删除管道或更改URL,则任务成功.

// This will succeed - no pipe
import Foundation
let task = NSTask()
task.launchPath = "/usr/bin/curl"
task.arguments = ["http://trove.nla.gov.au/newspaper/page/21704647"]
task.launch()
task.waitUntilExit()

// This will succeed - different URL
import Foundation
let task = NSTask()
let pipe = NSPipe()
task.launchPath = "/usr/bin/curl"
task.arguments = ["http://trove.nla.gov.au/newspaper/page/21704646"]
task.standardOutput = pipe
task.launch()
task2.waitUntilExit()

使用来自终端的curl直接运行任何示例都会成功,因此在从特定URL(以及其他一些URL)检索时,与NSTask的交互有一些内容,并且当存在管道时,这会导致cURL失败.

扩展@Hod的回答:推出的标准输出
进程被重定向到管道,但你的程序永远不会从中读取
其他管端.管道具有有限的缓冲区,例如参见
How big is the pipe buffer?
这解释了macOS上的管道缓冲区大小(最多)是64KB.

如果管道缓冲区已满,则启动的进程无法在其上写入
了.如果进程使用阻塞I / O,则对管道的write()将被阻塞,直到至少可以写入一个字节为止.那样做
永远不会发生在您的情况下,因此进程挂起并且不会终止.

仅当写入标准输出的金额时才会出现此问题
超过管道缓冲区大小,这解释了为什么它只发生在某些URL而不是其他URL.

作为解决方案,您可以从管道中读取,例如同

let data = pipe.fileHandleForReading.readDataToEndOfFile()

在等待进程终止之前.另一种选择是
使用异步读取,例如使用Real time NSTask output to NSTextView with Swift的代码:

pipe.fileHandleForReading.readabilityHandler = { fh in
    let data = fh.availableData
    // process data ...
}

这也可以读取标准输出和标准错误从一个过程通过管道没有阻塞.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读