Git Product home page Git Product logo

go-sh's Introduction

go-sh

wercker status Go Walker

If you depend on the old api, see tag: v.0.1

install: go get github.com/codeskyblue/go-sh

Pipe Example:

package main

import "github.com/codeskyblue/go-sh"

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")
session.SetDir("/")
# 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

contribute

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

support the author: alipay

thanks

this project is based on http://github.com/codegangsta/inject. 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.

go-sh's People

Contributors

codeskyblue avatar cure avatar diptadas avatar jackwakefield avatar mschneider avatar mswift42 avatar paulp avatar rishabhtulsian avatar tamalsaha avatar waigani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-sh's Issues

mutil command is hangling and no return

sh.Command("sh", "-c", fmt.Sprintf("oc delete all -n %v %v", namespace, labels)).
Command("sh", "-c", fmt.Sprintf("oc delete service -n %v %v", namespace, labels)).
Command("sh", "-c", fmt.Sprintf("oc delete configmap -n %v %v", namespace, labels)).
Command("sh", "-c", fmt.Sprintf("oc delete secret -n %v %v", namespace, labels)).
Output()

not return

Dont support uint in arguments

Hello!
i tried use this:

package main

import (
    "github.com/codeskyblue/go-sh"
    "log"
    "fmt"
)

func main() {
    port := uint(1)

    session := sh.NewSession()
    session.ShowCMD = true
    out, err := session.Command("/Users/Ivan/Downloads/redis-3.2.3/src/redis-server", "--port", port).Output()
    if err != nil {
        log.Fatal("ERROR: ", err)
    }
    fmt.Println("output is", string(out))
}

And have result:

/usr/local/go/bin/go run /Users/Ivan/Documents/GolangSpace/src/examples/test.go
[golang-sh]$ /Users/Ivan/Downloads/redis-3.2.3/src/redis-server --port

*** FATAL CONFIG FILE ERROR ***
Reading the configuration file, at line 2
>>> 'port'
Bad directive or wrong number of arguments
2016/09/09 15:55:25 ERROR: exit status 1
exit status 1

Is it possible to work with interactive shell?

I'm trying to figure out, is it possible to work with interactive shell commands?

e.g. as a first step, connect to mongodb:
mongo --quiet --host=localhost blog

then perform arbitrary number of commands, like
db.getCollection('posts').find({status:'INACTIVE'})

and then
exit

UPD
figured it out

Possible goroutine leak?

// the following code is from pipe.go
func (s *Session) WaitTimeout(timeout time.Duration) (err error) {
select {
case <-time.After(timeout):
s.Kill(syscall.SIGKILL)
return ErrExecTimeout
case err = <-Go(s.Wait):
return err
}
}

func Go(f func() error) chan error {
ch := make(chan error)
go func() {
ch <- f()
}()
return ch
}

if timeout happends, go func() {ch <- f() }(), will never return, since
A receive from an unbuffered channel happens before the send on that channel completes.

Error on Multiline-Output

When I run a command, that have Multiline-Output I get an Error:

.\main.go:6:21: newline in string
.\main.go:6:21: syntax error: unexpected newline, expecting comma or )

Line 6 in main.go is the import to this libary.

how to run command in daemon mode?

hi, if command like this, how to write?

nohup ~/dev/golang/myApps/src/gin_sample/gin_sample > /dev/null 2>&1&

my code works fine on foreignground, but can't run as daemon mode

package main

import (
    "github.com/codeskyblue/go-sh"
    "os"
    "syscall"
)

func main() {

    session := sh.NewSession()

    session.Command("nohup", "/Users/mmc/dev/golang/myApps/src/gin_sample/gin_sample")

    session.Stdout = os.NewFile(uintptr(syscall.Stdout), "/dev/null")
    session.Stderr = os.NewFile(uintptr(syscall.Stdout), "/dev/null")

    session.ShowCMD = true
    session.Run()
}

how to run in background?
thank you very much!

go-sh包 ,用到DOCKER操作指令时是无信息返回的。

go-sh包 ,用到DOCKER操作指令时是无信息返回的。
觉得非常奇怪。
go-sh包所在程序在宿主机上运行,运行docker --help是可以正常获得反馈,
但是使用docker ps -a之类的指令时,是无反馈回来的,
而在cmd面板ssh操作是可以正常反馈的。
是跨容器导致了这个问题吗,有办法解决吗?很头大

It is possible to redirect output?

It is possible to redirect output?

Like: mysqldump dbname | gzip -9 > dump.sql.gz
Or stderr: tar czf archive.tar.gz ./dir/ 2> /tmp/error.log

make && $PATH env variable

I need to execute make from go-sh, but I get this

configure: Setting lib to 'lib' (the default)
configure: Will try -pthread then -lpthread to enable POSIX Threads.
configure: CHECKS for site configuration
checking for gcc... gcc
checking whether the C compiler works... no

i.e. it can't find C compiler, I also checked $PATH and got an empty string

any idea how to make it work?

How use and operator?

Hello!
I have question.
I have this code:

session := sh.NewSession()
    session.SetTimeout(time.Second * 30)
    session.ShowCMD = true
    session.SetDir(repositoryPath)
    session.Command(
        "rm", "-f", archiveFile, "&&",
        "git", "archive", branchName, "--format", "tar", "--output", archiveFile,
    )

And debug message:
[golang-sh]$ rm -f /tmp/archive.tar && git archive origin/master --format tar --output /tmp/archive.tar
But second command not executed...
If i remove "rm", "-f", archiveFile, "&&",
Its work, but i need this "&&" operator.
What mistake?

output to console when exit status 1

Im encountering a issue where a exit status 1 command gives output to the console.

This is a issue for me as i need a specific text to appear in the console rather than the command output (the reason for this is, its used for a monitoring check and expects a certain syntax).

The pseudo example code is:
`
package := "randompackage"

output, err := sh.Command("dpkg-query", "--showformat='${Version}'", "--show", package).Output()
fmt.Println(err)
`

This will result in the following output in the console
dpkg-query: no packages found matching randompackage <------------- This being the commands failing output
exit status 1 <------------- This being the fmt.println

Let me know if you want any other info

Is there anyway to mute the output ?

It is possible to get the stdoutPipe?

It is possible to get the stdoutPipe?
just as func (c *Cmd) StdoutPipe() (io.ReadCloser, error)
if so, we can get the output when we exec the commands

echo $PATH 输出了单纯的字符串信息

      var r []byte
      if r, err = sh.Command("echo", "$PATH").Output(); err != nil {
        fmt.Println("filesystem anomalies")
        return
      }

它将直接输出 $PATH,理想状态下还是希望能够回馈环境变量列表

Help

out, err := sh.Command("./1", sh.Dir("/opt/wdsf/1/")).Output()
	fmt.Println(string(out), err)

截屏2022-06-22 23 34 04

fork/exec ./1: exec format error

Writing a bash like shell

Can we do something like this with the following with this plugin

$ > myshell
myshell > mycommand1 
myshell > mycommand2 some_sub_command --a some_args
myshell > exit
$ > 

Essentially have a shell that has it's own commands?

timeout and output

Hi, I am having problems in setting timeout in command and getting stdout at the same time. I used your example, and it works but I can't get output from this command:

 c := sh.Command("sleep", "3"); c.Start(); c.WaitTimeout(time.Seocnd)

I can use Output() function to get output but then timeout is not working.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.