Golang地表最狂(一)—— 标准库os/exec学习

地表最狂蓝胖子 · · 1000 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


伪粉表示stepping stone是真的燃

 “来到舞台接受到的目光 怎么都不一样 面对亲戚朋友父母亲的所有抵抗 我努力独立成长 守护着自己坚强 但为了妈妈每日翘楚以盼长大 才对 他们剑拔弩张 我是双截棍柔中带刚 不用去少林武当 Not afraid 地表最狂 举世无双 撑这束追光 不怕艰险的 别人不知道的力量 不知道的力量 各霸一方 遗忘你铩羽而归的地方 你会前进 步履艰辛 但终究得要习惯投降 想当然尔 盗铃掩耳 是你最大的致命伤 我按兵不动 有恃无恐 沉默的酝酿 纯粹出于我礼貌的开场 神华内敛才能以柔克刚 试探性衡量 暗箭难防 自尊受伤 成王败退 没什么两样 我运筹帷幄 仰望夕阳 你放弃抵抗 低头离场 但不用放在心上 是因为我们是地表最狂”---听到mdr-1abt燃烧的声音,真的进入一个自己的世界,码字也会变的飞快。。。。。

        第一次写技术博客(装b),不不不第一次在网上记笔记。。。嗯嗯,为什么想到记笔记,因为觉得今天看了导师给的学习计划,我感觉自己好像对学习Golang有了些许的激情,所以懒得去配的环境秒配,懒得装的goland秒装(感谢今天幸哥给的破解文件让老夫能够安心的撸代码)。

        所以看了第一周的学习计划,嗯,大概就是学习语言最基础的那些东西了,什么数据类型、常量等等,然后作业秒做,就剩一个最后的任务用——用标准库os/exec查询系统所有ip这个貌似很有挑战性的东西??貌似我这一周都可以好好学习这个标准库??

        步入正题,exec包执行外部命令,它将os.StartProcess进行包装使得它更容易映射到stdin和stdout,并且利用pipe连接I/o。

        1.func LookPath(file string) (string, error) //LookPath在环境变量中查找可执行二进制文件,如果file中包含一个斜杠,则直接根据绝对路径或者相对本目录的相对路径去查找。

func main() {

    f, err := exec.LookPath("D:/GOPATH/src/myGo/exec.go")

    if err != nil {

        fmt.Println(err)//输出错误

    }

    fmt.Println(f) //输出路径

}

        2.type Cmd //表示一个正在准备或者正在运行的外部命令

type Cmd struct {

    Path        string   //运行命令的路径,绝对路径或者相对路径

    Args        []string   // 命令参数

    Env          []string        //进程环境,如果环境为空,则使用当前进程的环境

    Dir          string   //指定command的工作目录,如果dir为空,则comman在调用进程所在当前目录中运行

    Stdin        io.Reader  //标准输入,如果stdin是nil的话,进程从null device中读取(os.DevNull),stdin也可以时一个文件,否则的话则在运行过程中再开一个goroutine去读取标准输入

    Stdout      io.Writer      //标准输出

    Stderr      io.Writer  //错误输出,如果这两个(Stdout和Stderr)为空的话,则command运行时将响应的文件描述符连接到os.DevNull

    ExtraFiles  []*os.File

    SysProcAttr  *syscall.SysProcAttr

    Process      *os.Process    //Process是底层进程,只启动一次

    ProcessState *os.ProcessState  //ProcessState包含一个退出进程的信息,当进程调用Wait或者Run时便会产生该信息.

}

        3.func Command(name string, arg ...string) *Cmd //command返回cmd结构来执行带有相关参数的命令,它仅仅设定cmd结构中的Path和Args参数,如果name参数中不包含路径分隔符,command使用LookPath来解决路径问题,否则的话就直接使用name;Args直接跟在command命令之后,所以在Args中不需要添加命令。

func main() {

    cmd := exec.Command("tr", "a-z", "A-Z")

    cmd.Stdin = strings.NewReader("some input")

    var out bytes.Buffer

    cmd.Stdout = &out

    err := cmd.Run()

    if err != nil {

        log.Fatal(err)

    }

    fmt.Printf("in all caps: %q\n", out.String())  //in all caps: "SOME INPUT"

}

        4.func (c *Cmd) CombinedOutput() ([]byte, error) //运行命令,并返回标准输出和标准错误

func main() {

    cmd := exec.Command("ls")  //查看当前目录下文件

    out, err := cmd.CombinedOutput()

    if err != nil {

        fmt.Println(err)        

    }

    fmt.Println(string(out))

}

        这里遇到一个ls:%l is not a valid Win32 application.的问题,看来可以请教导师一波。。。

        5.func (c *Cmd) Output() ([]byte, error) //运行命令并返回其标准输出

        6.func main() {

    cmd := exec.Command("ls") ///查看当前目录下文件

    out, err := cmd.Output()

    if err != nil {

        fmt.Println(err)

    }

    fmt.Println(string(out))//妈蛋,还是上面那个报错

}

注意:Output()和CombinedOutput()不能够同时使用,因为command的标准输出只能有一个,同时使用的话便会定义了两个,便会报错

        6.func (c *Cmd) Run() error //开始指定命令并且等待他执行结束,如果命令能够成功执行完毕,则返回nil,否则的话边会产生错误

        7.func (c *Cmd) Start() error //使某个命令开始执行,但是并不等到他执行结束,这点和Run命令有区别.然后使用Wait方法等待命令执行完毕并且释放响应的资源

func main() {

    cmd := exec.Command("ls")

    cmd.Stdout = os.Stdout //

    cmd.Run()

    fmt.Println(cmd.Start()) //exec: already started

}

注:一个command只能使用Start()或者Run()中的一个启动命令,不能两个同时使用.

        8.func (c *Cmd) StderrPipe() (io.ReadCloser, error) //StderrPipe返回一个pipe,这个管道连接到command的标准错误,当command命令退出时,Wait将关闭这些pipe

        9.func (c *Cmd) StdinPipe() (io.WriteCloser, error) //StdinPipe返回一个连接到command标准输入的管道pipe

func main() {

    cmd := exec.Command("cat")

    stdin, err := cmd.StdinPipe()

    if err != nil {

        fmt.Println(err)

    }

    _, err = stdin.Write([]byte("tmp.txt"))

    if err != nil {

        fmt.Println(err)

    }

    stdin.Close()

    cmd.Stdout = os.Stdout    //终端标准输出tmp.txt    

    cmd.Start()

}

        10.func (c *Cmd) StdoutPipe() (io.ReadCloser, error) //StdoutPipe返回一个连接到command标准输出的管道pipe

func main() {

    cmd := exec.Command("ls")

    stdout, err := cmd.StdoutPipe()  //指向cmd命令的stdout

    cmd.Start()

    content, err := ioutil.ReadAll(stdout)

    if err != nil {

        fmt.Println(err)

    }

    fmt.Println(string(content))    //输出ls命令查看到的内容

}

        11.func (c *Cmd) Wait() error //Wait等待command退出,他必须和Start一起使用,如果命令能够顺利执行完并顺利退出则返回nil,否则的话便会返回error,其中Wait会是放掉所有与cmd命令相关的资源   

type Error    //Error返回科执行二进制文件名字不能够执行的原因的错误

        12.func (e *Error) Error() string

type ExitError  //一个command不能够正常退出的error

        最后那道题还是这样解决的:


代卖
终端

        最后的问题是中文乱码,因为内网连不到GitHub,所以看来可以继续下一个笔记了:    "code.google.com/p/mahonia" mahonia包的使用。。。做事讲顺序,讲话要押韵,装完逼就跑真刺激。。。

本文来自:简书

感谢作者:地表最狂蓝胖子

查看原文:Golang地表最狂(一)—— 标准库os/exec学习

入群交流(该群和以上内容无关):Go中文网 QQ交流群:798786647 或 加微信入微信群:274768166 备注:入群; 公众号:Go语言中文网

1000 次点击  
加入收藏 微博
1 回复  |  直到 2018-09-10 23:58:29
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传