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 ...
随机推荐
- vue + ajax + php 接口的使用小接
vue + ajax + php 接口的使用小接 前端代码: (获取用户信息,并渲染页面) userinfor.html <!DOCTYPE html> <html lang=&qu ...
- JS判断浏览器类型与版本
在JS中判断浏览器的类型,估计是每个编辑过页面的开发人员都遇到过的问题.在众多的浏览器产品中,IE.Firefox.Opera.Safari........众多品牌却标准不一,因此时常需要根据不同的浏 ...
- java 静态代码块 代码块 构造函数 静态成员变量 成员变量的初始化顺序
没有父类的情况 1,静态代码块-->静态成员变量-->成员变量(实例属性)-->代码块-->构造函数 2, 静态代码块 和 静态成员变量 只会初始化一次 有父类的情况 1,父类 ...
- UITextView实现限制100字
placeHoderLable = [[UILabel alloc]initWithFrame:CGRectMake(3, 3, DeviceWidth-6, 40)]; //根据情况调节位置 pla ...
- 【学习】条码扫描器:QuaggaJS
QuaggaJS是条形码扫描器完全用JavaScript编写,支持实时对各类条码进行定位和解码,如EAN和CODE128.该库还能够使用getUserMedia获得直接访问用户的摄像头流.为了充分利用 ...
- 最美时光第三方UWP源码公开
自己大概写了一个星期的成果.. 使用了官方最美时光app的UI和图片资源,并没有调用官方接口 https://files.cnblogs.com/files/loyieking/NiceCountDo ...
- JAVA编程入门
java最早是由Sun公司基于C++开发而成的新一代编程语言也是现行下的主流行编程语言,其原始的主要用于嵌入式开发.java的第一个版本为JDK1.0,到2017年已经升级到JAK1.9版本.java ...
- Bootstrap 引用的标准模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- Spring装配Bean之Java代码装配bean
尽管通过组件扫描和自动装配实现Spring的自动化配置很方便也推荐,但是有时候自动配置的方式实现不了,就需要明确显示的配置Spring.比如说,想要将第三方库中的组件装配到自己的应用中,这样的情况下, ...
- (转)关于Tomcat的点点滴滴(体系架构、处理http请求的过程、安装和配置、目录结构、设置压缩和对中文文件名的支持、以及Catalina这个名字的由来……等)
转自:http://itfish.net/article/41668.html 总结Tomcat的体系架构.处理http请求的过程.安装和配置.目录结构.设置压缩和对中文文件名的支持.以及Cata ...