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):
UseSudoAsUserTimeoutContextEnvDirStdinStdoutStderrShellOnExit
But below methods cannot be chained(finalize):
RunOutputCombinedOutput
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