In swift5 would like to run a Process()
read both standardOutput
and standardError
without blocking, so I can parse them.
This example code once the line with for try await line in errorPipe.fileHandleForReading.bytes.lines
is called, the program execution is blocked. The standardOutput reader stops printing
import Foundation
let outputPipe = Pipe()
let errorPipe = Pipe()
let process = Process()
process.executableURL = URL(fileURLWithPath:"/sbin/ping")
process.arguments = ["google.com"]
process.standardOutput = outputPipe
process.standardError = errorPipe
try? process.run()
func processStdOut() async
{
for i in 0..<5 {
print("processStdOut X ", i)
try? await Task.sleep(nanoseconds: 1_000_000_000)
}
do {
for try await line in outputPipe.fileHandleForReading.bytes.lines {
print("stdout Line: \(line)")
}
} catch {
NSLog("processStdOut Error \(error.localizedDescription)")
}
NSLog("processStdOut finished")
}
func processStdErr() async
{
for i in 0..<5 {
print("processStdErr X ", i)
try? await Task.sleep(nanoseconds: 2_000_000_000)
}
do {
for try await line in errorPipe.fileHandleForReading.bytes.lines {
print("stderr Line: \(line)")
}
} catch {
NSLog("processStdErr Error \(error.localizedDescription)")
}
NSLog("processStdErr finished")
}
await withTaskGroup(of: Void.self) { group in
group.addTask {
await processStdErr()
}
group.addTask {
await processStdOut()
}
group.addTask {
process.waitUntilExit()
}
}
Note that if you force data into standardError by disconnecting the wifi or network standardOutput is unblocked again.
Anything else I should try?