Go better command run shell commands safely and handily.
More details please check godoc
go get github.com/futurist/better-command
// below is true and SAFE!!!:
import "github.com/futurist/better-command/command"
userID := httprequest.URL.Query().Get("userID") // maybe from a HACKER!!!
fmt.Printf("userID: %v", userID) // userID: ;rm -rf /
reflect.DeepEqual(
command.NewSh(`echo %s`, userID).Args,
[]string{"sh", "-c", "echo \\;rm\\ -rf\\ /"}
)
The argument for '%s'
will be always safely escaped.
The argument for %s
and "%s"
will be always safely escaped except $VAR
and ${VAR}
, thus you can use shell variables in side arguments.
The New
and NewSh
method argments just like fmt.Printf
, the first arg is formatString, rest is format arguments, but with one exception: they can only accept %s
as format placeholder. If you want use like %v
, you can manually invoke .toString()
method of the argument to pass as string.
import "github.com/futurist/better-command/command"
command.NewSh(`echo %s '%s'`, "logs: $HOME/$abc/logs", "logs: $HOME/$abc/logs")
.Stdout(os.Stdout)
.Stdin(os.Stdin)
.Timeout(time.Second*10)
.CombinedOutput()
There methods can be chained(in the middle):
UseSudo
AsUser
Timeout
Context
Env
Dir
Stdin
Stdout
Stderr
Shell
OnExit
But below methods cannot be chained(finalize):
Run
Output
CombinedOutput
import "github.com/futurist/better-command/command"
cmd := command.New([]string{"bash", "-c", "sleep 10; echo ok"})
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(time.Millisecond * 100)
cancel()
}()
cmd.Context(ctx).Run()
The command will be canceled in 100ms.
More details please see godoc:
https://pkg.go.dev/github.com/futurist/better-command/command