A go library for easy configure and run command chains. Such like pipelining in unix shells.

Overview

Go codecov Go Report Card Mentioned in Awesome Go

go-command-chain

A go library for easy configure and run command chains. Such like pipelining in unix shells.

Example

cat log_file.txt | grep error | wc -l
package main

import (
	"bytes"
	"fmt"
	"github.com/rainu/go-command-chain"
)

func main() {
	output := &bytes.Buffer{}

	err := cmdchain.Builder().
		Join("cat", "log_file.txt").
		Join("grep", "error").
		Join("wc", "-l").
		Finalize().WithOutput(output).Run()

	if err != nil {
		panic(err)
	}
	fmt.Printf("Errors found: %s", output)
}

For more examples how to use the command chain see examples.

Why you should use this library?

If you want to execute a complex command pipeline you could come up with the idea of just execute one command: the shell itself such like to following code:

package main

import (
	"os/exec"
)

func main() {
	exec.Command("sh", "-c", "cat log_file.txt | grep error | wc -l").Run()
}

But this procedure has some negative points:

  • you must have installed the shell - in correct version - on the system itself
    • so you are dependent on the shell
  • you have no control over the individual commands - only the parent process (shell command itself)
  • pipelining can be complex (redirection of stderr etc.) - so you have to know the pipeline syntax
    • maybe this syntax is different for shell versions

(advanced) features

input injections

Multiple different input stream for each command can be configured. This can be useful if you want to forward multiple input sources to one command.

package main

import (
	"github.com/rainu/go-command-chain"
	"strings"
)

func main() {
	inputContent1 := strings.NewReader("content from application itself\n")
	inputContent2 := strings.NewReader("another content from application itself\n")

	err := cmdchain.Builder().
		Join("echo", "test").WithInjections(inputContent1, inputContent2).
		Join("grep", "test").
		Join("wc", "-l").
		Finalize().Run()

	if err != nil {
		panic(err)
	}
}

forking of stdout and stderr

Stdout and stderr of each command can be forked to different io.Writer.

package main

import (
	"bytes"
	"github.com/rainu/go-command-chain"
)

func main() {
	echoErr := &bytes.Buffer{}
	echoOut := &bytes.Buffer{}
	grepErr := &bytes.Buffer{}
	
	err := cmdchain.Builder().
		Join("echo", "test").WithOutputForks(echoOut).WithErrorForks(echoErr).
		Join("grep", "test").WithErrorForks(grepErr).
		Join("wc", "-l").
		Finalize().Run()

	if err != nil {
		panic(err)
	}
}
You might also like...
Count once - Just once? no, when appear many it run once, but it can run many times

countOnce just once? no, when appear many it run once, but it can run many times

The slightly more awesome standard unix password manager for teams
The slightly more awesome standard unix password manager for teams

gopass Introduction gopass is a password manager for the command line written in Go. It supports all major operating systems (Linux, MacOS, BSD) as we

A modern UNIX ed (line editor) clone written in Go

ed (the awesome UNIX line editor) ed is a clone of the UNIX command-line tool by the same name ed a line editor that was nortorious for being and most

NYAGOS - The hybrid Commandline Shell between UNIX & DOS
NYAGOS - The hybrid Commandline Shell between UNIX & DOS

The Nihongo Yet Another GOing Shell English / Japanese NYAGOS is the commandline-shell written with the Programming Language GO and Lua. There are som

Fast, realtime regex-extraction, and aggregation into common formats such as histograms, numerical summaries, tables, and more!
Fast, realtime regex-extraction, and aggregation into common formats such as histograms, numerical summaries, tables, and more!

rare A file scanner/regex extractor and realtime summarizor. Supports various CLI-based graphing and metric formats (histogram, table, etc). Features

Command-line tool to load csv and excel (xlsx) files and run sql commands
Command-line tool to load csv and excel (xlsx) files and run sql commands

csv-sql supports loading and saving results as CSV and XLSX files with data processing with SQLite compatible sql commands including joins.

I like reading news but I also like the terminal. I am leaning and practicing my go.
I like reading news but I also like the terminal. I am leaning and practicing my go.

I made an api and didn't know how to use it. Screenshots The initial screen when you first run the app. The screen after you specify an id. This app u

 ReverseSSH - a statically-linked ssh server with reverse shell functionality for CTFs and such
ReverseSSH - a statically-linked ssh server with reverse shell functionality for CTFs and such

ReverseSSH A statically-linked ssh server with a reverse connection feature for simple yet powerful remote access. Most useful during HackTheBox chall

Comments
  • not working on my case

    not working on my case

    I am trying to parse nginx-access.log with:

    cat nginx-access.log | awk -F\" '{print $8}' | awk -F\, '{print $1}' | sort -n | uniq -c | sort -nr | head -10
    

    And using this library, I converted the command to:

    err := cmdchain.Builder().
    		Join("tail", outputFile).
    		Join("awk", "-F\"", "'{print $8}'").
    		Join("awk", "-F\\,", "'{print $1}'").
    		Join("sort", "-n").
    		Join("uniq", "-c").
    		Join("sort", "-fnr").
    		Join("head", "-n"+strconv.Itoa(line)).
    		Finalize().
    		WithOutput(output).
    		Run()
    

    But I am getting this:

    one or more command has returned an error: [0 - ; 1 - exit status 2]
    

    Any idea?

    opened by geraldvillorente 2
  • WithInjections causes panic

    WithInjections causes panic

    Calling WithInjections causes a panic and subsequent stack trace due to io.Copy being called on a command before its io streams have been created

    Go version: 1.17.6

    input := strings.NewReader("Hello")
    err := cmdchain.Builder().
            Join("cat").WithInjections(input).
            Finalize().
            WithOutput(os.Stdout).
            Run()
    

    Causes the output

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x1076af7]
    
    goroutine 18 [running]:
    io.copyBuffer({0x10d96a0, 0xc000100000}, {0x0, 0x0}, {0x0, 0x0, 0x0})
            /usr/local/go/src/io/io.go:423 +0x197
    io.Copy(...)
            /usr/local/go/src/io/io.go:382
    os.genericReadFrom(0x10b61a0, {0x0, 0x0})
            /usr/local/go/src/os/file.go:162 +0x5d
    os.(*File).ReadFrom(0x0, {0x0, 0x0})
            /usr/local/go/src/os/file.go:156 +0x55
    io.copyBuffer({0x10d95a0, 0xc0000ac020}, {0x0, 0x0}, {0x0, 0x0, 0x0})
            /usr/local/go/src/io/io.go:409 +0x14b
    io.Copy(...)
            /usr/local/go/src/io/io.go:382
    github.com/rainu/go-command-chain.(*chain).combineStreamForCommand.func1(0x0, {0x0, 0x0})
            /Users/WHS03/go/pkg/mod/github.com/rainu/[email protected]/builder_streams.go:136 +0xaa
    created by github.com/rainu/go-command-chain.(*chain).combineStreamForCommand
            /Users/WHS03/go/pkg/mod/github.com/rainu/[email protected]/builder_streams.go:133 +0x2f7
    Hello
    

    Caused by builder_streams.go invoking io.Copy when the cmd.Stdin of /bin/cat is nil

    The command does run to completion but exits with error code 2

    opened by wd-hopkins 1
Owner
null
Hasura-fzf - This command has a fzf-like UI that allows you to find and run the file version used by the hasura command

hasura-fzf This command has a fzf-like UI that allows you to find and run the fi

Shoki Hata 5 Sep 29, 2022
Brigodier is a command parser & dispatcher, designed and developed for command lines such as for Discord bots or Minecraft chat commands. It is a complete port from Mojang's "brigadier" into Go.

brigodier Brigodier is a command parser & dispatcher, designed and developed to provide a simple and flexible command framework. It can be used in man

Minekube 16 Dec 15, 2022
PickleShell - best shell for unix-like os

?? PickleShell shell for super users Compilation Windows go build -o PickleShell.exe

null 1 Nov 8, 2021
Pack a Go workflow/function as a Unix-style pipeline command

tpack Pack a Go workflow/function as a Unix-style pipeline command. Wiki In Unix-like computer operating systems, a pipeline is a mechanism for inter-

Eugene R. 55 Nov 9, 2022
A command line tool for quickly converting Unix timestamps to human readable form.

stamp A command line tool to quickly format a Unix timestamp in a human-readable form. Installation Go is required to build this software. To just bui

Ricco Førgaard 1 Oct 30, 2021
A command line utility that automagically replaces UNIX timestamps with human interpretable timestamps.

Unfy unfy is a command line utility that automagically identifies and translated UNIX timestamps (since epoch) to human readable timestamps. Example B

Jens Rantil 41 Oct 22, 2022
Declaratively configure your Hydra server with Terraform.

terraform-provider-hydra The Terraform Hydra provider is a plugin for Terraform that allows for declarative management of a Hydra instance. You can fi

Determinate Systems 34 Nov 9, 2022
UltiTuner: a small helper tool to configure functions for Ultimaker S-Line printers

UltiTuner UltiTuner is a small helper tool to configure functions for Ultimaker

Christian Schmied 6 Apr 25, 2022
Watcher - A simple command line app to watch files in a directory for changes and run a command when files change!

Watcher - Develop your programs easily Watcher watches all the files present in the directory it is run from of the directory that is specified while

Geet Sethi 1 Mar 27, 2022
This is a command that simply prints "ok" onto your screen whenever you run the "ok" command

ok This is a command that simply prints "ok" onto your screen whenever you run the ok command Installation (Linux) Download the latest release and sud

ErrorNoInternet 7 Sep 16, 2022