go-runner
Go package exposing a simple interface for executing commands, enabling easy
mocking and wrapping of executed commands.
The Runner interface is basic and minimal, but it is sufficient for most use
cases. This makes it easy to mock Runner for testing purposes.
It's also easy to create wrapper runners which modify commands before executing
them. The Sudo
struct is a simple example of this.
Import
import "github.com/krystal/go-runner"
Interface
type Runner interface {
Run(
stdin io.Reader,
stdout, stderr io.Writer,
command string,
args ...string,
) error
RunContext(
ctx context.Context,
stdin io.Reader,
stdout, stderr io.Writer,
command string,
args ...string,
) error
Env(env ...string)
}
Usage
Basic:
var stdout bytes.Buffer
r := runner.New()
_ = r.Run(nil, &stdout, nil, "echo", "Hello world!")
fmt.Print(stdout.String())
Hello world!
Environment:
var stdout bytes.Buffer
r := runner.New()
r.Env("USER=johndoe", "HOME=/home/johnny")
_ = r.Run(nil, &stdout, nil, "sh", "-c", `echo "Hi, ${USER} (${HOME})"`)
fmt.Print(stdout.String())
Hi, johndoe (/home/johnny)
Stdin, Stdout, and Stderr:
stdin := bytes.NewBufferString("Hello world!")
var stdout, stderr bytes.Buffer
r := runner.New()
err := r.Run(
stdin, &stdout, &stderr,
"sh", "-c", "cat; echo 'Oh noes! :(' >&2",
)
if err != nil {
fmt.Println(err)
}
fmt.Print(stderr.String())
fmt.Print(stdout.String())
Oh noes! :(
Hello world!
Failure:
var stdout, stderr bytes.Buffer
r := runner.New()
err := r.Run(
nil, &stdout, &stderr,
"sh", "-c", "echo 'Hello world!'; echo 'Oh noes! :(' >&2; exit 3",
)
if err != nil {
fmt.Printf("%s: %s", err.Error(), stderr.String())
}
exit status 3: Oh noes! :(
Context:
var stdout bytes.Buffer
ctx, cancel := context.WithTimeout(
context.Background(), 1*time.Second,
)
defer cancel()
r := runner.New()
err := r.RunContext(
ctx, nil, &stdout, nil,
"sh", "-c", "sleep 0.5 && echo 'Hello world!'",
)
if err != nil {
fmt.Println(err)
}
fmt.Print(stdout.String())
Hello world!
Sudo (requires NOPASS
in sudoers file):
var stdout bytes.Buffer
r := runner.New()
sudo := &runner.Sudo{Runner: r}
_ = sudo.Run(nil, &stdout, nil, "whoami")
sudo.User = "web"
_ = sudo.Run(nil, &stdout, nil, "whoami")
fmt.Print(stdout.String())
root
web
Documentation
Please see the
Go Reference
for documentation and examples.
License
MIT