Go基础篇【第5篇】: 内置库模块 exec
Package exec runs external commands. It wraps os.StartProcess to make it easier to remap stdin and stdout, connect I/O with pipes, and do other adjustments.
Unlike the "system" library call from C and other languages, the os/exec package intentionally does not invoke the system shell and does not expand any glob patterns or handle other expansions, pipelines, or redirections typically done by shells. The package behaves more like C's "exec" family of functions. To expand glob patterns, either call the shell directly, taking care to escape any dangerous input, or use the path/filepath package's Glob function. To expand environment variables, use package os's ExpandEnv.
Note that the examples in this package assume a Unix system. They may not run on Windows, and they do not run in the Go Playground used by golang.org and godoc.org.
func LookPath
func LookPath(file string) (string, error)
在环境变量PATH指定的目录中搜索可执行文件,如file中有斜杠,则只在当前目录搜索。
即:默认在系统的环境变量里查找给定的可执行命令文件,如果查找到返回路径,否则报错,unix是$PATH,windows是$PATH$。可提供相对路径下进行查找,并返回相对路径
type Cmd
type Cmd struct {
// Path是将要执行的命令的路径。
//
// 该字段不能为空,如为相对路径会相对于Dir字段。
Path string
// Args保管命令的参数,包括命令名作为第一个参数;如果为空切片或者nil,相当于无参数命令。
//
// 典型用法下,Path和Args都应被Command函数设定。
Args []string
// Env指定进程的环境,如为nil,则是在当前进程的环境下执行。
Env []string
// Dir指定命令的工作目录。如为空字符串,会在调用者的进程当前目录下执行。
Dir string
// Stdin指定进程的标准输入,如为nil,进程会从空设备读取(os.DevNull)
Stdin io.Reader
// Stdout和Stderr指定进程的标准输出和标准错误输出。
//
// 如果任一个为nil,Run方法会将对应的文件描述符关联到空设备(os.DevNull)
//
// 如果两个字段相同,同一时间最多有一个线程可以写入。
Stdout io.Writer
Stderr io.Writer
// ExtraFiles指定额外被新进程继承的已打开文件流,不包括标准输入、标准输出、标准错误输出。
// 如果本字段非nil,entry i会变成文件描述符3+i。
//
// BUG: 在OS X 10.6系统中,子进程可能会继承不期望的文件描述符。
// http://golang.org/issue/2603
ExtraFiles []*os.File
// SysProcAttr保管可选的、各操作系统特定的sys执行属性。
// Run方法会将它作为os.ProcAttr的Sys字段传递给os.StartProcess函数。
SysProcAttr *syscall.SysProcAttr
// Process是底层的,只执行一次的进程。
Process *os.Process
// ProcessState包含一个已经存在的进程的信息,只有在调用Wait或Run后才可用。
ProcessState *os.ProcessState
// 内含隐藏或非导出字段
}
Cmd代表一个正在准备或者在执行中的外部命令。
注:exec在执行调用系统命令时,会先对需要执行的操作进行一次封装,然后在执行。封装后的命令对象具有以上struct属性。而封装方式即使用下边的command函数。
func Command
func Command(name string, arg ...string) *Cmd
函数返回一个*Cmd,用于使用给出的参数执行name指定的程序。返回值只设定了Path和Args两个参数。
如果name不含路径分隔符(如果不是相对路径),将使用LookPath获取完整路径(就是用默认的全局变量路径);否则直接使用name。参数arg不应包含命令名。
cmd := exec.Command("go","version")
fmt.Println(cmd.Args, cmd.Path)
注:在调用命令执行封装时,如果不提供相对路径,系统会使用LookPath获取完整路径;即这里可以给一个相对路径。
以上操作只会将命令进行封装,相当于告诉系统将进行哪些操作,但是执行时无法获取相关信息,因此我们还需要连接到命令执行时相关的输入输出pipe。################################################################################################
我们可以通过指定一个对象连接到对应的管道进行传输参数(stdinpipe),获取输出(stdoutpipe),获取错误(stderrpipe)
func (*Cmd) StdinPipe
func (c *Cmd) StdinPipe() (io.WriteCloser, error) //err 返回的是执行函数时的错误
package main import (
"fmt"
"os"
"os/exec"
) func main() {
cmd := exec.Command("cat")
stdin, err := cmd.StdinPipe() //指定stdin连接StdinPipe,然后操作stdin就实现了对command的参数传递
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()
}
StdinPipe方法返回一个在命令Start后与命令标准输入关联的管道。Wait方法获知命令结束后会关闭这个管道。必要时调用者可以调用Close方法来强行关闭管道,例如命令在输入关闭后才会执行返回时需要显式关闭管道。
func (*Cmd) StdoutPipe
func (c *Cmd) StdoutPipe() (io.ReadCloser, error) //err 返回的是执行函数时的错误
func main() {
cmd := exec.Command("ls")
stdout, err := cmd.StdoutPipe() //指向cmd命令的stdout,然后就可以从stdout读出信息
cmd.Start()
content, err := ioutil.ReadAll(stdout)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(content)) //输出ls命令查看到的内容
}
StdoutPipe方法返回一个在命令Start后与命令标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。但是在从管道读取完全部数据之前调用Wait是错误的;同样使用StdoutPipe方法时调用Run函数也是错误的。
func (*Cmd) StderrPipe
func (c *Cmd) StderrPipe() (io.ReadCloser, error) //err 返回的是执行函数时的错误
import (
"fmt"
"io/ioutil"
"os/exec"
) func main() {
c := exec.Command("mv", "hello")
i, err := c.StderrPipe()
if err != nil {
fmt.Printf("Error: %s\n", err)
return
}
if err = c.Start(); err != nil { //表示命令正确执行了
fmt.Printf("Error: %s\n", err)
}
b, _ := ioutil.ReadAll(i) //读取命令执行的返回结果(命令执行结果的错误信息)
if err := c.Wait(); err != nil {
fmt.Printf("Error: %s\n", err) //Error: exit status 1 mv: missing file argument Try `mv --help' for more information.
}
fmt.Println(string(b))
}
StderrPipe方法返回一个在命令Start后与命令标准错误输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。但是在从管道读取完全部数据之前调用Wait是错误的;同样使用StderrPipe方法时调用Run函数也是错误的
#################################################################
func (*Cmd) Run
func (c *Cmd) Run() error
Run执行c包含的命令,并阻塞直到完成。
如果命令成功执行,stdin、stdout、stderr的转交没有问题,并且返回状态码为0,方法的返回值为nil【执行Run函数的返回状态,正确执行Run函数,并不代表正确执行了命令】;如果函数没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。
即:该命令只会执行且阻塞到执行结束,如果执行函数有错则返回报错信息,没错则返回nil,并不会返回执行结果。
func (*Cmd) Start
func (c *Cmd) Start() error
Start开始执行c包含的命令,但并不会等待该命令完成即返回。Wait方法会返回命令的返回状态码并在命令返回后释放相关的资源。
func (*Cmd) Wait
func (c *Cmd) Wait() error
Wait会阻塞直到该命令执行完成,该命令必须是被Start方法开始执行的。
如果命令成功执行,stdin、stdout、stderr的转交没有问题,并且返回状态码为0,方法的返回值为nil;如果命令没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。Wait方法会在命令返回后释放相关的资源。
func (*Cmd) Output
func (c *Cmd) Output() ([]byte, error)
执行命令并返回标准输出的切片。不用通过pipe方式获取命令的执行结果
import (
"fmt"
"os/exec"
) func main() {
c, err := exec.Command("date").Output()
if err != nil {
fmt.Println(err)
}
fmt.Println(string(c)) // Sat Jan 4 17:07:36 2014 这个是标准库里的例子
}
func (*Cmd) CombinedOutput
func (c *Cmd) CombinedOutput() ([]byte, error)
执行命令并返回标准输出和错误输出合并的切片。
Go基础篇【第5篇】: 内置库模块 exec的更多相关文章
- Go基础篇【第8篇】: 内置库模块 bytes [二]
type Reader ¶ type Reader struct { // 内含隐藏或非导出字段 } Reader类型通过从一个[]byte读取数据,实现了io.Reader.io.Seeker.io ...
- Go基础篇【第1篇】: 内置库模块 OS
os包提供了操作系统函数的不依赖平台的接口.设计为Unix风格的,虽然错误处理是go风格的:失败的调用会返回错误值而非错误码.通常错误值里包含更多信息.os包的接口规定为在所有操作系统中都是一致的.非 ...
- Go基础篇【第8篇】: 内置库模块 bytes [一]
bytes包实现了操作[]byte的常用函数.本包的函数和strings包的函数相当类似. func Compare func Compare(a, b []byte) int Compare函数返回 ...
- Go基础篇【第6篇】: 内置库模块 flag
import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1. ...
- Go基础篇【第4篇】: 内置库模块 bufio
bufio包实现了有缓冲的I/O.它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本I/O的帮助函数的对象. 即:为了解决CPU与磁盘IO ...
- Go基础篇【第2篇】: 内置库模块 fmt
fmt官方文档说明:https://studygolang.com/pkgdoc import "fmt" mt包实现了类似C语言printf和scanf的格式化I/O.格式化动作 ...
- Go内置库模块 flag
import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1. ...
- day05 模块以及内置常用模块用法
内置常用模块详解: 1 time 2 datetime 3 random 4 os 5 sys 6 shutil 7 shelve 8 xml 9 configparser 10 hashlib ...
- 【CobaltStrike】对CobaltStrike内置功能模块的了解
对CobaltStrike内置功能模块的了解 0x00 右键功能列表 Interact 打开beacon Access dump hashes 获取hash Elevate 提权 Golden Tic ...
随机推荐
- EditPlus行首行尾批量添加字符 以及其它常用正则
打开EditPlus,输入多行数据,快捷键ctrl+h 打开替换窗口,选择"正则表达式"替换 行首批量添加 查找"^" 替换为"我是行首aaa&q ...
- Elasticsearch学习笔记 一
本文版权归博客园和作者吴双本人共同所有 转载和爬虫请注明原文地址 www.cnblogs.com/tdws. 本文参考和学习资料 <ES权威指南> 一.基本概念 存储数据到ES中的行为叫做 ...
- DevOps之内容分发网络CDN
唠叨话 关于德语噢屁事的知识点,仅提供专业性的精华汇总,具体知识点细节,参考教程网址,如需帮助,请留言. <内容分发网络CDN(Content Delivery Network)> 关于虚 ...
- 如何用IDEA一步一步开发WebService服务器端
工具:IntelliJ IDEA 15.0.4 IDEA这款IDE还是非常强大的,对WebService也有很好的支持.下面我们来一步一步的实现WebService服务器端: 第一步,新建一个工程:F ...
- Python 第十三节 文件操作
A 1.首先文件读写操作有以下几种模式: a\a+ w\w+ r\r+ a模式:追加_写入模式,写入指针默认在开头,如果文件存在将在开头追加写入,如果文件不存在将创建文件再写入. a+模式: ...
- (转)Java中使用正则表达式的一个简单例子及常用正则分享
转自:http://www.jb51.net/article/67724.htm 这篇文章主要介绍了Java中使用正则表达式的一个简单例子及常用正则分享,本文用一个验证Email的例子讲解JAVA中如 ...
- Redis 学习笔记-入门
Redis特点: 1.速度快 2.支持丰富的数据类型:字符串.哈希列表.集合 3.操作具有原子性,所有Redis操作都是原子操作 4.多实用工具,可应用如缓存,消息队列,应用程序中任何短期数据,如we ...
- 【前端】主流API-promise解析,js基础。
前言 在js领域,promise出现的时间已经很久了,从jquery的$.get().done().fail() 这样的API开始,到现在的es6默认支持的new Promise(),它的出现无疑使异 ...
- Mybatis通用Mapper
极其方便的使用Mybatis单表的增删改查 项目地址:http://git.oschina.net/free/Mapper 优点? 不客气的说,使用这个通用Mapper甚至能改变你对Mybatis单表 ...
- Ionic3 遇到的一些错误-submodule update -q --init --recursive
解决方法: ionic start myTabs tabs --skip-deps cd .\myTabs cnpm install --save-dev ionic serve > npm i ...