Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Analysis on the use of script commands in Go

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "case analysis of the use of Go execution script commands". In daily operation, I believe that many people have doubts about the use of Go execution script commands. Xiaobian consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts of "the use of Go execution script commands". Next, please follow the editor to study!

Brief introduction

In the development, we may encounter the need to call the script in the program, or involve the interaction between the two languages. The author encountered the need to call python in go before, and then applied the go-python3 library in the code. In fact, calling the script of python in go is also a solution. This article will introduce how to run a shell script in go and parse its source code accordingly.

Program use case

Test_command.go

Package learnimport ("fmt"os/exec"testing") func TestCmd (t * testing.T) {if o, e: = exec.Command (". / test.sh", "1", "2"). Output (); e! = nil {fmt.Println (e)} else {fmt.Println (string (o))}}

Test.sh

#! / bin/basha=$1b=$2echo $aecho $b

The above example means to run the script test.sh, and the input parameter is 1 ~ 2. What is written in the script is relatively simple, which is to print these two input parameters. In fact, the crux of the problem lies in the method of exec.Command (). Let's get to the bottom of it and find out.

Source code parsing func Command (name string, arg... string) * Cmd {cmd: = & Cmd {Path: name, Args: append ([] string {name}, arg...),} if filepath.Base (name) = = name {if lp, err: = LookPath (name) Err! = nil {cmd.lookPathErr = err} else {cmd.Path = lp}} return cmd} / / Base returns the last element of path. / / the trailing path delimiter is deleted before the last element is extracted. / / if the path is empty, Base returns "." / / if the path consists entirely of delimiters, Base returns a single delimiter. Func Base (path string) string {if path = = "" {return "."} / / Strip trailing slashes. For len (path) > 0 & & os.IsPathSeparator (path [len (path)-1]) {path = path [0: len (path)-1]} / / Throw away volume name path = path [len (VolumeName (path)):] / / Find the last element i: = len (path)-1 for I > = 0 & &! os.IsPathSeparator (path [I]) {irel -} if I > = 0 { Path = path [iTun1:]} / / If empty now It had only slashes. If path = "" {return string (Separator)} return path} / / LookPath searches for an executable named file input parameter in a directory named by the PATH environment variable. If the file contains a slash, it will be tried directly without referring to the PATH. The result may be an absolute path or a path relative to the current directory. Func LookPath (file string) (string, error) {if strings.Contains (file, "/") {err: = findExecutable (file) if err = nil {return file, nil} return "", & Error {file, err}} path: = os.Getenv ("PATH") for _ Dir: = range filepath.SplitList (path) {if dir = = "{/ / Unix shell semantics: path element"means". " Dir = "."} path: = filepath.Join (dir, file) if err: = findExecutable (path); err = = nil {return path, nil}} return ", & Error {file, ErrNotFound}} / / find the executable command func findExecutable (file string) error {d, err: = os.Stat (file) if err! = nil {return err} if m: = d.Mode () ! m.IsDir () & & masks 0111! = 0 {return nil} return os.ErrPermission}

From the analysis of the exec.Command () source code above, we can see that this function just looks for an executable file with the same name as path and builds a Cmd object to return. It is worth noting that when we enter path if it is not a specific path to an executable file, then we will go to the registered path in the PATH environment variable to find a command with the same name as path. If it is not found at this time, an error will be reported.

Well, next, let's take a look at who is this Cmd, what is its use, and how to use it. Let's take a look at what's in the Cmd structure.

The / / Cmd structure represents an external command that is ready or executing / / an Cmd object cannot be reused after a Run,Output or CombinedOutput method call. Type Cmd struct {/ / Path represents the path to run the command / / this field is the only field that needs to be assigned, cannot be an empty string, / / and if Path is a relative path, then refer to the directory pointed to by the Dir field Path string / / Args this field represents the parameters required to invoke the command Where Path exists in the form of Args [0] when running a command / / if this parameter is empty, then run the command directly using Path / in more common scenarios Both Path and Args parameters are used when invoking the command Args [] string / / Env represents the environment variable of the current process / / each entry in the Env array exists in the form of "key=value" / / if Env is nil, the process created by running the command there will use the environment variable of the current process / / if there is a duplicate key in the process Then the last value in this key will be used. / / there is a special case in Windows that if SYSTEMROOT is missing from the system, or if the environment variable is not set to an empty string, then it is an append operation. Env [] string / / Dir represents the running path of the command / / if Dir is an empty string, then the command will run on the running path of the current process Dir string / / Stdin represents the system's standard input stream / / if Stdin is a * os.File, then the standard input of the process will be directly connected to the file. Stdin io.Reader / / Stdout represents the standard output stream / / if the StdOut is a * os.File, then the standard input of the process will be connected directly to the file. / / it is worth noting that if StdOut and StdErr are the same object, only one co-program can call Writer Stdout io.Writer Stderr io.Writer / / ExtraFiles at a time to specify additional open files inherited by the new process. It does not include standard input, standard output, or standard error. If it is not zero, item I becomes the file descriptor 3 + I. / / the first three elements of ExtraFiles are ExtraFiles that stdin,stdout,stderr / / ExtraFiles is not supported on Windows [] * os.File SysProcAttr * syscall.SysProcAttr / / when the command runs, Process is the process represented by the command Process * os.Process / / ProcessState contains information about an exiting process, which is available after calling Wait or Run. ProcessState * os.ProcessState ctx context.Context / / ctx can be used to time out control lookPathErr error / / if an error occurs when calling LookPath to find a path, assign a value to this field finished bool / / when Wait is called once, it will be set to True Prevent repeated calls to childFiles [] * os.File closeAfterStart [] io.Closer closeAfterWait [] io.Closer goroutine [] func () error / / a series of functions that are executed together when you call Satrt to start executing the command. Each function assigns a goroutine to execute errch chan error / / to be used in conjunction with the previous field. Through this chan, the result of the above function is passed to the current goroutine waitDone chan struct {}}.

Above we parse some of the fields of the Cmd structure, which can be understood as Cmd is an abstraction of a command life cycle. Let's analyze the method of Cmd and see how it is used.

The / / Run method starts executing the command and waits for it to finish / / if the command runs without problems copying stdin, stdout, and stder, and exits with zero exit, the error returned is nil. / / if the command starts but does not complete successfully, the error type is of type * ExitError. Other error types may be returned in other cases. / / if the called goroutine has locked the operating system thread with runtime.LockOSThread and modified any inheritable OS-level thread state (for example, Linux or Plan 9 namespace), the new process will inherit the caller's thread state. The func (c * Cmd) Run () error {if err: = c.Start (); err! = nil {return err} return c.Wait ()} / / Start method starts the specified command without waiting for it to complete. / / if Start returns successfully, the c.Process field will be set. / once the command is run, the Wait method returns the exit code and releases the relevant resources. Func (c * Cmd) Start () error {if c.lookPathErr! = nil {c.closeDescriptors (c.closeAfterStart) c.closeDescriptors (c.closeAfterWait) return c.lookPathErr} if runtime.GOOS = = "windows" {lp, err: = lookExtensions (c.Path C.Dir) if err! = nil {c.closeDescriptors (c.closeAfterStart) c.closeDescriptors (c.closeAfterWait) return err} c.Path = lp} if c.Process! = nil {return errors.New ("exec: already started")} if c.ctx! = nil {select {case 0 {c.errch = make (chan error) Len (c.goroutine)) for _, fn: = range c.goroutine {go func (fn func () error) {c.errch

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report