Go实战--go语言中执行shell脚本(The way to go)

时间:2022-09-02 23:26:24

生命不止,继续go go go !!!

接触linux的人对shell一定不陌生,君不见那些噼里啪啦敲的飞快的服务端程序猿都是在键入,ls cd cat 等。

何为shell?
Simply put, the shell is a program that takes your commands from the keyboard and gives them to the operating system to perform. In the old days, it was the only user interface available on a Unix computer. Nowadays, we have graphical user interfaces (GUIs) in addition to command line interfaces (CLIs) such as the shell.

On most Linux systems a program called bash (which stands for Bourne Again SHell, an enhanced version of the original Bourne shell program, sh, written by Steve Bourne) acts as the shell program. There are several additional shell programs available on a typical Linux system. These include: ksh, tcsh and zsh.

Shell 是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

os/exec package
go中为我们提供了一个os/exec包:用于运行外部的命令。

Cmd结构

type Cmd struct {
Path string

Args []string

Env []string

Dir string

Stdin io.Reader

Stdout io.Writer

Stderr io.Writer

ExtraFiles []*os.File

SysProcAttr *syscall.SysProcAttr

Process *os.Process

ProcessState *os.ProcessState
}

其中, Stdout specify the process’s standard output

func Command
原型:

func Command(name string, arg ...string) *Cmd

作用:Command returns the Cmd struct to execute the named program with the given arguments.
例如:
cmd := exec.Command(“/bin/bash”, “-c”, “ls”)
cmd := exec.Command(“tr”, “a-z”, “A-Z”)

func (*Cmd) Run

func (c *Cmd) Output() ([]byte, error)

作用:开始运行并等待结束。

这里需要注意Run和Start的区别:
Start starts the specified command but does not wait for it to complete.
开始运行不等待结束。

应用代码

package main

import (
"bytes"
"fmt"
"log"
"os/exec"
)


func exec_shell(s string) {
cmd := exec.Command("/bin/bash", "-c", s)
var out bytes.Buffer

cmd.Stdout = &out
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", out.String())
}

func main() {
exec_shell("uname ")
}

输出:
Linux

应用代码2

package main

import (
"fmt"
"os/exec"
"sync"
"strings"
)

func exe_cmd(cmd string, wg *sync.WaitGroup) {
fmt.Println(cmd)
parts := strings.Fields(cmd)
out, err := exec.Command(parts[0],parts[1]).Output()
if err != nil {
fmt.Println("error occured")
fmt.Printf("%s", err)
}
fmt.Printf("%s", out)
wg.Done()
}

func main() {
wg := new(sync.WaitGroup)
commands := []string{"echo newline >> foo.o", "echo newline >> f1.o", "echo newline >> f2.o"}
for _, str := range commands {
wg.Add(1)
go exe_cmd(str, wg)
}
wg.Wait()
}

这段代码用到了sync包,之后会介绍的。