SwiftCommand

Platforms: macOS/Linux/Windows* Supported swift versions

*Windows 支持目前仅为实验性功能。


一个围绕 Foundation.Process 的封装,灵感来源于 Rust 的 std::process::Command。 这个包可以方便地调用命令行程序并处理它们的 I/O。

安装

您可以使用 Swift Package Manager 安装此包,方法是将其包含在您的包的依赖项中

let package = Package(
    // ...
    dependencies: [
        // other dependencies...
        .package(
            url: "https://github.com/Zollerboy1/SwiftCommand.git",
            from: "1.4.0"
        ),
    ],
    // ...
)

用法

使用这个包非常容易。

在开始之前,请确保您已经导入了 SwiftCommand 模块

import SwiftCommand

现在它可以像这样使用

let output = try Command.findInPath(withName: "echo")!
                        .addArgument("Foo")
                        .waitForOutput()

print(output.stdout)
// Prints 'Foo\n'

这将阻塞线程直到命令终止。 如果您想在等待命令终止时执行其他工作,可以使用 async/await API。

let output = try await Command.findInPath(withName: "echo")!
                              .addArgument("Foo")
                              .output

print(output.stdout)
// Prints 'Foo\n'

指定命令 I/O

假设您有一个名为 SomeFile.txt 的文件,内容如下:

Foo
Bar
Baz

然后您可以像这样设置命令的 stdin 和 stdout

let catProcess = try Command.findInPath(withName: "cat")!
                            .setStdin(.read(fromFile: "SomeFile.txt"))
                            .setStdout(.pipe)
                            .spawn()

let grepProcess = try Command.findInPath(withName: "grep")!
                             .addArgument("Ba")
                             .setStdin(.pipe(from: catProcess.stdout))
                             .setStdout(.pipe)
                             .spawn()

for try await line in grepProcess.stdout.lines {
    print(line)
}
// Prints 'Bar' and 'Baz'

try catProcess.wait()
try grepProcess.wait()
// Ensure the processes are terminated before exiting the parent process

这在 Swift 中实现了您通常在终端中编写的内容,例如:

cat < SomeFile.txt | grep Ba

如果您没有指定 stdin、stdout 或 stderr,并且也没有捕获输出(例如使用 waitForOutput()),那么它们默认将继承父进程的相应句柄。 例如,以下程序的 stdout 是 Bar\n

import SwiftCommand

try Command.findInPath(withName: "echo")!
           .addArgument("Bar")
           .wait()