package module
v0.1.0 Latest Latest

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2021 License: Apache-2.0 Imports: 14 Imported by: 26


CI PkgGoDev


install: go get

Pipe Example:

package main

import ""

func main() {
	sh.Command("echo", "hello\tworld").Command("cut", "-f2").Run()

Because I like os/exec, go-sh is very much modelled after it. However, go-sh provides a better experience.

These are some of its features:

  • keep the variable environment (e.g. export)
  • alias support (e.g. alias in shell)
  • remember current dir
  • pipe command
  • shell build-in commands echo & test
  • timeout support

Examples are important:

sh: echo hello
go: sh.Command("echo", "hello").Run()

sh: export BUILD_ID=123
go: s = sh.NewSession().SetEnv("BUILD_ID", "123")

sh: alias ll='ls -l'
go: s = sh.NewSession().Alias('ll', 'ls', '-l')

sh: (cd /; pwd)
go: sh.Command("pwd", sh.Dir("/")).Run()

sh: test -d data || mkdir data
go: if ! sh.Test("dir", "data") { sh.Command("mkdir", "data").Run() }

sh: cat first second | awk '{print $1}'
go: sh.Command("cat", "first", "second").Command("awk", "{print $1}").Run()

sh: count=$(echo "one two three" | wc -w)
go: count, err := sh.Echo("one two three").Command("wc", "-w").Output()

sh(in ubuntu): timeout 1s sleep 3
go: c := sh.Command("sleep", "3"); c.Start(); c.WaitTimeout(time.Second) # default SIGKILL
go: out, err := sh.Command("sleep", "3").SetTimeout(time.Second).Output() # set session timeout and get output)

sh: echo hello | cat
go: out, err := sh.Command("cat").SetInput("hello").Output()

sh: cat # read from stdin
go: out, err := sh.Command("cat").SetStdin(os.Stdin).Output()

sh: ls -l > /tmp/listing.txt # write stdout to file
go: err := sh.Command("ls", "-l").WriteStdout("/tmp/listing.txt")

If you need to keep env and dir, it is better to create a session

session := sh.NewSession()
session.SetEnv("BUILD_ID", "123")
# then call cmd
session.Command("echo", "hello").Run()
# set ShowCMD to true for easily debug
session.ShowCMD = true

By default, pipeline returns error only if the last command exit with a non-zero status. However, you can also enable pipefail option like bash. In that case, pipeline returns error if any of the commands fail and for multiple failed commands, it returns the error of rightmost failed command.

session := sh.NewSession()
session.PipeFail = true
session.Command("cat", "unknown-file").Command("echo").Run()

By default, pipelines's std-error is set to last command's std-error. However, you can also combine std-errors of all commands into pipeline's std-error using session.PipeStdErrors = true.

for more information, it better to see docs. Go Walker


If you love this project, starring it will encourage the coder. Pull requests are welcome.

support the author: alipay


this project is based on thanks for the author.

the reason to use Go shell

Sometimes we need to write shell scripts, but shell scripts are not good at working cross platform, Go, on the other hand, is good at that. Is there a good way to use Go to write shell like scripts? Using go-sh we can do this now.



Package go-sh is intended to make shell call with golang more easily. Some usage is more similar to os/exec, eg: Run(), Output(), Command(name, args...)

But with these similar function, pipe is added in and this package also got shell-session support.

Why I love golang so much, because the usage of golang is simple, but the power is unlimited. I want to make this pakcage got the sample style like golang.

// just like os/exec
sh.Command("echo", "hello").Run()

// support pipe
sh.Command("echo", "hello").Command("wc", "-c").Run()

// create a session to store dir and env

// shell buildin command - "test"
sh.Test("dir", "mydir")

// like shell call: (cd /; pwd)
sh.Command("pwd", sh.Dir("/")) same with sh.Command(sh.Dir("/"), "pwd")

// output to json and xml easily
v := map[string] int {}
err = sh.Command("echo", `{"number": 1}`).UnmarshalJSON(&v)




This section is empty.


View Source
var ErrExecTimeout = errors.New("execute timeout")


func Go

func Go(f func() error) chan error

func Test

func Test(exp string, arg string) bool

expression can be d,dir, f,file, link

if sh.Test("dir", "mydir") {
	fmt.Println("mydir exists")


type Dir

type Dir string

type Session

type Session struct {
	Env     map[string]string
	Stdin   io.Reader
	Stdout  io.Writer
	Stderr  io.Writer
	ShowCMD bool // enable for debug

	// additional pipe options
	PipeFail      bool // returns error of rightmost no-zero command
	PipeStdErrors bool // combine std errors of all pipe commands
	// contains filtered or unexported fields

func Command

func Command(name string, a ...interface{}) *Session
out, err := sh.Command("echo", "hello").Output()
fmt.Println(string(out), err)

func Echo

func Echo(in string) *Session

func InteractiveSession

func InteractiveSession() *Session

func NewSession

func NewSession() *Session

func (*Session) Alias

func (s *Session) Alias(alias, cmd string, args ...string)
s := NewSession()
s.Alias("alias_echo_hello", "echo", "hello")
out, err := s.Command("alias_echo_hello", "world").Output()
if err != nil {

hello world

func (*Session) AppendStdout

func (s *Session) AppendStdout(f string) error

func (*Session) Call

func (s *Session) Call(name string, a ...interface{}) error

combine Command and Run

func (*Session) CombinedOutput

func (s *Session) CombinedOutput() (out []byte, err error)

func (*Session) Command

func (s *Session) Command(name string, a ...interface{}) *Session
s := NewSession()
out, err := s.Command("echo", "hello").Output()
if err != nil {

Example (Pipe)
s := NewSession()
out, err := s.Command("echo", "hello", "world").Command("awk", "{print $2}").Output()
if err != nil {


func (*Session) Getwd

func (s *Session) Getwd() string

func (*Session) Kill

func (s *Session) Kill(sig os.Signal)

func (*Session) Output

func (s *Session) Output() (out []byte, err error)

func (*Session) Run

func (s *Session) Run() (err error)

func (*Session) SetDir

func (s *Session) SetDir(dir string) *Session

func (*Session) SetEnv

func (s *Session) SetEnv(key, value string) *Session

func (*Session) SetInput

func (s *Session) SetInput(in string) *Session

func (*Session) SetStdin

func (s *Session) SetStdin(r io.Reader) *Session

func (*Session) SetTimeout

func (s *Session) SetTimeout(d time.Duration) *Session

func (*Session) Start

func (s *Session) Start() (err error)

start command

func (*Session) Test

func (s *Session) Test(expression string, argument string) bool

expression can be dir, file, link

func (*Session) UnmarshalJSON

func (s *Session) UnmarshalJSON(data interface{}) (err error)

unmarshal shell output to decode json

func (*Session) UnmarshalXML

func (s *Session) UnmarshalXML(data interface{}) (err error)

unmarshal command output into xml

func (*Session) Wait

func (s *Session) Wait() error

Should be call after Start() only catch the last command error

func (*Session) WaitTimeout

func (s *Session) WaitTimeout(timeout time.Duration) (err error)

func (*Session) WriteStdout

func (s *Session) WriteStdout(f string) error


Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL