一个简单的 Swift 封装,用于处理 Process
,支持 Swift 并发和从 stdout
和 stderr
流式输出。
macOS 10.15 及以上
通过 Xcode (File > Add Packages...) 或将 Coquille 添加到项目的 Package.swift
文件中,将 Coquille 添加到你的项目中
dependencies: [
.package(url: "https://github.com/alexrozanski/Coquille.git", from: "0.3.0")
]
Coquille 公开了自己的 Process
类,你可以使用它来执行命令。Process.run()
是一个 async
函数,所以你可以直接 await
退出码
import Coquille
let process = Process(commandString: "pwd"))
_ = try await process.run() // Prints `pwd` to `stdout`
// Use `command:` for more easily working with variable command-line arguments
let deps = ["numpy", "torch"]
let process = Process(command: .init("python3", arguments: ["-m", "pip", "install"] + deps)))
_ = try await process.run()
默认情况下,Process
不会将产生的进程的任何输出管道到 stdout
和 stderr
。 这可以通过 printStdout
和 printStderr
进行配置
import Coquille
let process = Process(commandString: "brew install wget", printStdout: true))
_ = try await process.run() // Pipes standard output to `stdout` but will not pipe error output to `stderr`
你也可以为 stdout 和 stderr 传递一个 OutputHandler
,它将流式传输来自两者的内容
import Coquille
let process = Process(
commandString: "swift build",
stdout: { stdout in
...
},
stderr: { stderr in
...
})
_ = try await process.run() // Streams standard and error output to the handlers provided to `stdout:` and `stderr:`
// `isSuccess` can be used to test the exit code for success
let hasRuby = (try await Process(commandString: "which ruby").run()).isSuccess
// Use `errorCode` to get a nonzero exit code
if let errorCode = (try await Process(commandString: "swift build").run()).errorCode {
switch errorCode {
case 127:
// Command not found
default:
...
}
}
主要的 Process.run()
函数签名是
public func run() async throws -> Status
它允许你使用 Swift 并发来执行子进程并 await
退出状态。 但是,如果你想支持取消,你可以使用另一个 run()
函数
public func run(with completionHandler: @escaping ((Status) -> Void)) -> ProcessCancellationHandle
它立即返回一个不透明的 ProcessCancellationHandle
类型,你可以调用它的 cancel()
方法来取消执行,进程状态通过 completionHandler
闭包传递。
感谢 Ben Chatelain 撰写的关于拦截 stdout 的 博客文章,该文章用于实现测试套件中的一些测试。