When you are working on a project recently, you need to use Golang to invoke the command line in the operating system to execute a shell command or call a third-party program, which naturally uses the Exec.command of Golang.
But if you use native exec directly. command creates a lot of duplicate code, searches the web for a lap and does not find the exec. command the corresponding package, simply self-encapsulated a, named Gocommand. Currently supports Linux and Windows, and you are welcome to submit code on GitHub to complement the implementation of other platforms.
The following is a description of the Gocommand library implementation ideas:
Package gocommand//command line interface type Commander interface {//execute command line and return result//args: Command line arguments//return: PID of the process, command line result, error message exec (args ... s Tring) (int, string, error)//asynchronously executes the command line and returns the result with Channel//Stdout:chan result//args: Command line arguments//return: pid//of the process exception: command line within the thread occurs Error, Panic exception Execasync (stdout Chan string, args ... string) int//execution command line (ignoring return value)//args: Command line arguments//return: Error message execnowait (args (... string) Error}
Gocommand The current command-line execution function is derived from the Commander interface, currently the interface defines 3 functions, namely: executing the command line disease return results; Execute command line asynchronously and get results; Execute command line and ignore result.
Package Gocommandimport ("runtime")//Command initialization function func Newcommand () Commander {var cmd commanderswitch runtime. GOOS {case ' Linux ': cmd = Newlinuxcommand () case "windows": cmd = Newwindowscommand () Default:cmd = Newlinuxcommand ()} return cmd}
Create a command implementation, and according to the current operating system, return the corresponding implementation function, currently only implemented Linux and Windows, (Mac left to you the great God (local tyrants)), where Linuxcommand code implementation is as follows:
Package Gocommandimport ("Io/ioutil" "OS" "Os/exec" "syscall")//linuxcommand struct type linuxcommand struct {}// Linuxcommand initialization function func Newlinuxcommand () *linuxcommand {return &linuxcommand{}}//execute command line and return result//args: Command line arguments// Return: PID of the process, command line result, error message func (LC *linuxcommand) Exec (args ... string) (int, string, error) {args = append ([]string{"-C"} , args ...) CMD: = Exec.command (OS. Getenv ("SHELL"), args ...) Cmd. Sysprocattr = &syscall. Sysprocattr{}outpip, err: = cmd. Stdoutpipe () if err! = Nil {return 0, "", Err}err = cmd. Start () if err! = Nil {return 0, "", err}out, err: = Ioutil. ReadAll (OUTPIP) if err! = Nil {return 0, "", Err}return cmd. Process.pid, String (out), nil}//executes the command line asynchronously and returns the result with the channel//Stdout:chan result//args: Command line arguments//return: pid//exception of the process: life within the association Panic exception func (LC *linuxcommand) Execasync (stdout Chan string, args ... string) int {var Pidchan = make (chan int, 1) When a row error occurs Go func () {args = append ([]string{"-C"}, args ...) CMD: = Exec.command (OS. Getenv ("SHELL"), args ...) Cmd. Sysprocattr = &sYscall. Sysprocattr{}outpip, err: = cmd. Stdoutpipe () if err! = Nil {panic (err)}err = cmd. Start () if err! = Nil {panic (err)}pidchan <-cmd. Process.pidout, err: = Ioutil. ReadAll (OUTPIP) if err! = Nil {panic (err)}stdout <-string (Out)} () return <-pidchan}//execute command line (Ignore return value)//args: Command line arguments//R Eturn: Error message func (LC *linuxcommand) execnowait (args ... string) error {args = append ([]string{"-C"}, args ...) CMD: = Exec.command (OS. Getenv ("SHELL"), args ...) Cmd. Stdout = OS. Stdoutcmd.stderr = OS. Stderrcmd.sysprocattr = &syscall. Sysprocattr{}err: = cmd. Run () Return err}
The EXEC function blocks after executing the command line until the command execution results are obtained; The Execasync function internally uses a co-process to execute the command line and passes the result through the Chan variable in the parameter; Execnowait will saidy execute the command line. The implementation on the Windows platform is similar, except that the shell command has been replaced with CMD.
Examples of use are:
Package Mainimport ("Log" "Github.com/lizongshen/gocommand") func Main () {_, out, err: = Gocommand. Newcommand (). Exec ("ls/") if err! = Nil {log. Panic (Err)}log. Println (Out)}
Unit test Case for code:
[Lizongshen@localhost gocommand]$ go testbin Dev home lib64mnt proc run SRV tmp Varboot etc lib mediaopt root sbin sys Usrpassok gocommand0.007s
GitHub Open Source Address: Https://github.com/lizongshen/gocommand.