https://github.com/broothie/cob
A Go package for building shell commands
https://github.com/broothie/cob
go shell
Last synced: about 2 months ago
JSON representation
A Go package for building shell commands
- Host: GitHub
- URL: https://github.com/broothie/cob
- Owner: broothie
- License: mit
- Created: 2025-02-23T08:40:16.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-23T08:44:21.000Z (over 1 year ago)
- Last Synced: 2025-02-23T09:27:19.491Z (over 1 year ago)
- Topics: go, shell
- Language: Go
- Homepage:
- Size: 0 Bytes
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# `cob` 🌽 COmmand Builder
[](https://pkg.go.dev/github.com/broothie/cob)
[](https://codecov.io/gh/broothie/cob)
[](https://github.com/broothie/cob/actions/workflows/gosec.yml)
[](https://goreportcard.com/report/github.com/broothie/cob)
`cob` is a Go package for building and running `*exec.Cmd` objects.
## Installation
```shell
go get github.com/broothie/cob@latest
```
## Documentation
Detailed documentation can be found at [pkg.go.dev](https://pkg.go.dev/github.com/broothie/cob).
## Usage
```go
// Easily build `*exec.Cmd` objects:
cmd, err := cob.New(ctx, "echo",
cob.AddArgs("Hello", "World"),
cob.AddEnv("SHELL", "bash"),
cob.SetStdout(os.Stdout),
)
// Or, run them and easily get `stdout` and `stderr`:
stdout, stderr, cmd, err := cob.Output(ctx, "echo", cob.AddArgs("Hello", "World"))
```
Here is a list of all available options:
```go
cmd, err := cob.New(ctx, "echo",
cob.SetArgs("Hello", "World"), // Set args directly
cob.AddArgs("more", "args"), // Add to existing args
cob.SetEnv("SHELL=bash"), // Set env directly
cob.AddEnv("SHELL", "bash"), // Add to existing env
cob.SetStdin(os.Stdin), // Set stdin directly
cob.AddStdins(someReader), // Add to existing stdin
cob.SetStdout(os.Stdout), // Set stdout directly
cob.AddStdouts(someWriter), // Add to existing stdout
cob.SetStderr(os.Stderr), // Set stderr directly
cob.AddStderrs(errorWriter), // Add to existing stderr
cob.SetDir("/tmp"), // Set working directory
cob.SetExtraFiles(os.Stdin), // Set extra files directly
cob.AddExtraFiles(someFile), // Add to existing extra files
cob.SetSysProcAttr(&syscall.SysProcAttr{}), // Set process attributes
cob.SetWaitDelay(time.Second), // Set timeout for Wait()
)
```
## Why?
The `*exec.Cmd` API isn't terrible by any means,
I just find building the actual `*exec.Cmd` objects to be somewhat cumbersome.
With this library we go from this:
```go
stdout := new(bytes.Buffer)
stderr := new(bytes.Buffer)
cmd := exec.CommandContext(ctx, "command", "arg1", "arg2")
cmd.Stdin = os.Stdin
cmd.Stdout = io.MultiWriter(stdout, os.Stdout)
cmd.Stderr = stderr
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, value))
if err := cmd.Run(); err != nil {
return err
}
```
to this:
```go
stdout, stderr, cmd, err := cmd.Output(ctx, "command",
cob.AddArgs("arg1", "arg2"),
cob.SetStdin(os.Stdin),
cob.AddStdouts(os.Stdout),
cob.AddEnv(key, value),
)
if err != nil {
return err
}
```
which I personally find clearer and more concise.