gpt4 book ai didi

swift - 如何运行 shell 命令并让它在命令运行时打印输出?

转载 作者:行者123 更新时间:2023-11-30 10:48:35 27 4
gpt4 key购买 nike

我使用下面的函数来运行 shell 命令,但我似乎无法让它在命令运行时打印输出。例如,如果我运行/usr/sbin/system_profiler,我必须等到命令执行完毕才能看到输出。

如何在命令仍在运行时打印 shell 命令的输出?

func runCommand(cmd: String, args: String...) -> (output: [String], error: [String], exitCode: Int32) {
print("running shell command")
var output: [String] = []
var error: [String] = []
let task = Process()
task.launchPath = cmd
task.arguments = args
let outpipe = Pipe()
task.standardOutput = outpipe
let errpipe = Pipe()
task.standardError = errpipe
task.launch()
let outdata = outpipe.fileHandleForReading.readDataToEndOfFile()
if var string = String(data: outdata, encoding: .utf8) {
string = string.trimmingCharacters(in: .newlines)
output = string.components(separatedBy: "\n")
}
let errdata = errpipe.fileHandleForReading.readDataToEndOfFile()
if var string = String(data: errdata, encoding: .utf8) {
string = string.trimmingCharacters(in: .newlines)
error = string.components(separatedBy: "\n")
}
task.waitUntilExit()
let status = task.terminationStatus
print("shell end")
return (output, error, status)
}

最佳答案

您必须使任务异步并readInBackgroundAndNotify

像这样(未经测试),它使用 terminationHandler 并添加 readCompletionNotification 观察者来获取通知。

var output = ""

func runCommand(cmd: String, args: String..., completion: @escaping (String, String, Int32) -> Void) {
print("running shell command")
let task = Process()
task.launchPath = cmd
task.arguments = args
let outpipe = Pipe()
task.standardOutput = outpipe
let errpipe = Pipe()
task.standardError = errpipe
task.terminationHandler = { [unowned self] returnedTask in
NotificationCenter.default.removeObserver(self,
name: FileHandle.readCompletionNotification,
object: (returnedTask.standardOutput as! Pipe).fileHandleForReading)
let status = returnedTask.terminationStatus
if status == 0 {
completion(output, "", status)
} else {
let errorData = errpipe.fileHandleForReading.readDataToEndOfFile()
let errorString = String(data:errorData, encoding: .utf8)!
completion("", errorString, status)
}
}
let outputHandle = (task.standardOutput as! Pipe).fileHandleForReading
NotificationCenter.default.addObserver(forName: FileHandle.readCompletionNotification, object: outputHandle, queue: OperationQueue.current, using: { notification in
if let data = notification.userInfo?[NSFileHandleNotificationDataItem] as? Data, !data.isEmpty {
output.append(String(data: data, encoding: . utf8)!)
} else {
task.terminate()
return
}
outputHandle.readInBackgroundAndNotify()
})
outputHandle.readInBackgroundAndNotify()
task.launch()
}

如果您想在接收时打印数据,请将 output.append(String(data: data,encoding: .utf8)!) 替换为 print(String(data: data,encoding) : .utf8)!) 然后你可能也不需要完成处理程序。

关于swift - 如何运行 shell 命令并让它在命令运行时打印输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55196219/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com