Avatar
ありがとうございます!その点が原因のようでした。 >cat /path/to/適当にでかい(テキスト)ファイル >Objective-C, NSTask Buffer Limitation >The NSPipe buffer limit seems to be 4096 bytes 上記の通り4096 bytesが制限という話が見つかりました。 ただし10kbのテキストファイルで試した所、問題なく処理が完了し、出力も全て出力される動きでした。 >(あるいはstdout/stderrを全部 /dev/null に繋げてみるとか) 下記とした場合に処理が完了しました。 static var xcodebuild: String { """ xcodebuild \ -scheme "BuildSampleProject" \ -project ~/"Downloads/tmp/BuildSampleProject/BuildSampleProject.xcodeproj" \ -configuration "Release" \ -archivePath ~"/Downloads/tmp/BuildSampleProject/build/BuildSampleProject.xcarchive" \ archive \ 1>/dev/null 2>&1 """ } (edited)
I'm using NSTask to run an external utility which returns a long string of data. The problem is that when the returned string exceeds a large amount of data (around 32759 chars) it becomes null or
2:45 AM
また実行中にPipeを随時吸い出せるように下記の通り書いてみたところ、こちらもxcodebuildの処理が無事に完了しました。 /// completion版 static func execute(command: String, currentDirectoryURL: URL? = nil, completion: @escaping (Result<String, CommandError>) -> ()) { let process = Process() process.launchPath = "/bin/zsh" process.arguments = ["-cl", command] process.currentDirectoryURL = currentDirectoryURL let pipe = Pipe() process.standardOutput = pipe process.standardError = pipe process.standardOutput = pipe process.standardError = pipe do { try process.run() } catch { completion(.failure(.failedInRunning)) return } var output = "" let saveOutputInProgress = { guard let _output = String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) else { return } output += _output Thread.sleep(forTimeInterval: 0.5) } // Processが完了するまで、Taskがキャンセルされていないかを監視 while process.isRunning { do { try Task.checkCancellation() } catch { process.terminate() completion(.failure(.cancel)) return } saveOutputInProgress() } saveOutputInProgress() if process.terminationStatus != 0 { completion(.failure(.exitStatusIsInvalid(process.terminationStatus, output))) return } completion(.success(output)) }
🎉 5