Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/Zollerboy1/SwiftCommand
A wrapper around Foundation.Process, inspired by Rust's std::process::Command.
https://github.com/Zollerboy1/SwiftCommand
Last synced: about 2 months ago
JSON representation
A wrapper around Foundation.Process, inspired by Rust's std::process::Command.
- Host: GitHub
- URL: https://github.com/Zollerboy1/SwiftCommand
- Owner: Zollerboy1
- License: mit
- Created: 2022-08-13T15:22:32.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-04-23T12:56:20.000Z (5 months ago)
- Last Synced: 2024-04-23T15:26:57.768Z (5 months ago)
- Language: Swift
- Size: 85 KB
- Stars: 75
- Watchers: 4
- Forks: 5
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# SwiftCommand
![Platforms: macOS/Linux/Windows\*](https://img.shields.io/badge/Platforms-macOS%20%7C%20Linux%20%7C%20Windows%2A-F05138)
[![Supported swift versions](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FZollerboy1%2FSwiftCommand%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/Zollerboy1/SwiftCommand)*\*Windows support is only experimental for now.*
---
A wrapper around `Foundation.Process`, inspired by Rust's
`std::process::Command`. This package makes it easy to call command line
programs and handle their I/O.## Installation
You can install this package using the Swift Package Manager, by including it in
the dependencies of your package:```swift
let package = Package(
// ...
dependencies: [
// other dependencies...
.package(
url: "https://github.com/Zollerboy1/SwiftCommand.git",
from: "1.4.0"
),
],
// ...
)
```## Usage
Using this package is very easy.
Before you start, make sure that you've imported the `SwiftCommand` module:
```swift
import SwiftCommand
```Now it can be used like this:
```swift
let output = try Command.findInPath(withName: "echo")!
.addArgument("Foo")
.waitForOutput()print(output.stdout)
// Prints 'Foo\n'
```This blocks the thread until the command terminates. You can use the
`async`/`await` API instead, if you want to do other work while waiting for the
command to terminate:```swift
let output = try await Command.findInPath(withName: "echo")!
.addArgument("Foo")
.outputprint(output.stdout)
// Prints 'Foo\n'
```### Specifying command I/O
Suppose that you have a file called `SomeFile.txt` that looks like this:
```
Foo
Bar
Baz
```You can then set stdin and stdout of commands like this:
```swift
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
```This is doing in Swift, what you would normally write in a terminal like this:
```bash
cat < SomeFile.txt | grep Ba
```If you don't specify stdin, stdout, or stderr, and also don't capture the output
(using e.g. `waitForOutput()`), then they will by default inherit the
corresponding handle of the parent process. E.g. the stdout of the following
program is `Bar\n`:```swift
import SwiftCommandtry Command.findInPath(withName: "echo")!
.addArgument("Bar")
.wait()
```