Skip to content

JohnStarich/goenable

Repository files navigation

goenable

Write Bash builtins in Go.

goenable makes it easy to extend Bash with Go, without executing in a separate process. Using Bash's enable builtin, goenable is loaded into the Bash runtime and provides helpers to load custom plugins.

Quick start

Download and set up the goenable binary:

curl -fsSL "https://github.com/JohnStarich/goenable/releases/download/v0.2.2/goenable-$(uname -s)-$(uname -m).so" > goenable.so

enable -f ./goenable.so goenable  # Load goenable
help goenable                     # Print usage

If you download this repo, you can also build the example plugins and try them out. You'll need Go 1.11+ installed, so if you're using macOS, then you can run brew install go@1.11.

make plugins                      # Build the example plugins
goenable load ./out/hello output  # Load the hello plugin
eval "$output"                    # Prepare functions from the hello plugin

hello
# Hello, world!

Write a plugin

goenable uses Go plugins to load and run custom Go code inside the Bash process.

Start with this pow plugin as your main.go:

package main

import (
	"fmt"
	"math"
	"os"
	"strconv"
)

// Usage returns the full set of documentation for this plugin
func Usage() string {
	return "pow X Y\nPrints X to the power of Y"
}

// Load runs any set up required by this plugin
func Load() error {
	return nil
}

// Unload runs any tear down required by this plugin
func Unload() {
}

// Run executes this plugin with the given arguments
func Run(args []string) int {
	if len(args) != 2 {
		// Print usage error and return with exit code 2
		fmt.Fprintln(os.Stderr, Usage())
		return 2
	}
	x, _ := strconv.ParseFloat(args[0], 64)
	y, _ := strconv.ParseFloat(args[1], 64)
	// Print pow result and return success with exit code 0
	fmt.Println(math.Pow(x, y))
	return 0
}

func main() {}

Build it with go build -o pow -buildmode=plugin main.go

Make sure you have a Bash terminal open and the goenable.so binary, then run:

# Start goenable with the 'enable' Bash builtin
enable -f ./path/to/your/goenable.so goenable

goenable load ./pow output  # Load the pow plugin
eval "$output"              # Prepare the pow plugin function

pow 1 10
# 1
pow 2 2.2
# 4.59479341998814

Check out other plugins like hello for more working examples.

Contributing

All contributions are welcome!

If you have suggestions for new features or run into a problem, please submit an issue.