非常教程

Go参考手册

os

os/exec

  • import "os/exec"
  • Overview
  • Index
  • Examples

概观

包 exec 执行外部命令。它包装了 os.StartProcess ,以便重新映射 stdin 和 stdout ,使用管道连接 I/O 并进行其他调整。

与来自 C 和其他语言的“系统”库调用不同,os/exec 包有意不调用系统shell,并且不会扩展任何 glob 模式或处理通常由 shell 执行的其他扩展,管道或重定向。该软件包的行为更像 C 的 “exec” 系列功能。要扩展 glob 模式,请直接调用外壳,注意避开任何危险输入,或者使用 path/filepath 包的 Glob 函数。要扩展环境变量,请使用 package os 的 ExpandEnv 。

请注意,此包中的示例假定为Unix系统。它们可能无法在Windows上运行,并且它们不会在golang.org和godoc.org使用的Go Playground中运行。

Index

  • Variables
  • func LookPath(file string) (string, error)
  • type Cmd
  • func Command(name string, arg ...string) *Cmd
  • func CommandContext(ctx context.Context, name string, arg ...string) *Cmd
  • func (c *Cmd) CombinedOutput() ([]byte, error)
  • func (c *Cmd) Output() ([]byte, error)
  • func (c *Cmd) Run() error
  • func (c *Cmd) Start() error
  • func (c *Cmd) StderrPipe() (io.ReadCloser, error)
  • func (c *Cmd) StdinPipe() (io.WriteCloser, error)
  • func (c *Cmd) StdoutPipe() (io.ReadCloser, error)
  • func (c *Cmd) Wait() error
  • type Error
  • func (e *Error) Error() string
  • type ExitError
  • func (e *ExitError) Error() string

例子

Cmd.CombinedOutput Cmd.Output Cmd.Run Cmd.Start Cmd.StderrPipe Cmd.StdinPipe Cmd.StdoutPipe Command CommandContext Command (Environment) LookPath

包文件

exec.go exec_unix.go lp_unix.go

变量

ErrNotFound 是如果路径搜索未能找到可执行文件导致的错误。

var ErrNotFound = errors.New("executable file not found in $PATH")

func LookPath(显示源文件)

func LookPath(file string) (string, error)

LookPath 在由 PATH 环境变量命名的目录中搜索名为 file 的可执行二进制文件。如果文件包含斜线,则直接尝试并且不会咨询 PATH 。结果可能是相对于当前目录的绝对路径或路径。

package main

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

func main() {
	path, err := exec.LookPath("fortune")
	if err != nil {
		log.Fatal("installing fortune is in your future")
	}
	fmt.Printf("fortune is available at %s\n", path)
}

type Cmd(显示源文件)

Cmd 代表正在准备或运行的外部命令。

调用它的 Run,Output 或 CombinedOutput 方法后,Cmd 不能重用。

type Cmd struct {
        // Path is the path of the command to run.
        //
        // This is the only field that must be set to a non-zero
        // value. If Path is relative, it is evaluated relative
        // to Dir.
        Path string

        // Args holds command line arguments, including the command as Args[0].
        // If the Args field is empty or nil, Run uses {Path}.
        //
        // In typical use, both Path and Args are set by calling Command.
        Args []string

        // Env specifies the environment of the process.
        // Each entry is of the form "key=value".
        // If Env is nil, the new process uses the current process's
        // environment.
        // If Env contains duplicate environment keys, only the last
        // value in the slice for each duplicate key is used.
        Env []string

        // Dir specifies the working directory of the command.
        // If Dir is the empty string, Run runs the command in the
        // calling process's current directory.
        Dir string

        // Stdin specifies the process's standard input.
        // If Stdin is nil, the process reads from the null device (os.DevNull).
        // If Stdin is an *os.File, the process's standard input is connected
        // directly to that file.
        // Otherwise, during the execution of the command a separate
        // goroutine reads from Stdin and delivers that data to the command
        // over a pipe. In this case, Wait does not complete until the goroutine
        // stops copying, either because it has reached the end of Stdin
        // (EOF or a read error) or because writing to the pipe returned an error.
        Stdin io.Reader

        // Stdout and Stderr specify the process's standard output and error.
        //
        // If either is nil, Run connects the corresponding file descriptor
        // to the null device (os.DevNull).
        //
        // If Stdout and Stderr are the same writer, and have a type that can be compared with ==,
        // at most one goroutine at a time will call Write.
        Stdout io.Writer
        Stderr io.Writer

        // ExtraFiles specifies additional open files to be inherited by the
        // new process. It does not include standard input, standard output, or
        // standard error. If non-nil, entry i becomes file descriptor 3+i.
        ExtraFiles []*os.File

        // SysProcAttr holds optional, operating system-specific attributes.
        // Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
        SysProcAttr *syscall.SysProcAttr

        // Process is the underlying process, once started.
        Process *os.Process

        // ProcessState contains information about an exited process,
        // available after a call to Wait or Run.
        ProcessState *os.ProcessState
        // contains filtered or unexported fields
}

func Command(显示源文件)

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

命令返回 Cmd 结构来执行具有给定参数的命名程序。

它仅在返回的结构中设置 Path 和 Args 。

如果名称不包含路径分隔符,Command 将尽可能使用 LookPath 将名称解析为完整路径。否则,它直接使用名称作为路径。

返回的 Cmd 的 Args 字段由命令名称和后面的 arg 元素构成,所以 arg 不应包含命令名称本身。例如,Command(“echo”,“hello”)。Args0 始终是名称,而不是可能解析的路径。

package main

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

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())
}

示例(环境)

package main

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

func main() {
	cmd := exec.Command("prog")
	cmd.Env = append(os.Environ(),
		"FOO=duplicate_value", // ignored
		"FOO=actual_value",    // this value is used
	)
	if err := cmd.Run(); err != nil {
		log.Fatal(err)
	}
}

func CommandContext(显示源文件)

func CommandContext(ctx context.Context, name string, arg ...string) *Cmd

CommandContext 与 Command 相似,但包含一个上下文。

如果上下文在命令完成之前完成,则提供的上下文用于终止进程(通过调用 os.Process.Kill )。

package main

import (
	"context"
	"os/exec"
	"time"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancel()

	if err := exec.CommandContext(ctx, "sleep", "5").Run(); err != nil {
		// This will fail after 100 milliseconds. The 5 second sleep
		// will be interrupted.
	}
}

func (*Cmd) CombinedOutput(显示源文件)

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

CombinedOutput 运行该命令并返回其组合标准输出和标准错误。

package main

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

func main() {
	cmd := exec.Command("sh", "-c", "echo stdout; echo 1>&2 stderr")
	stdoutStderr, err := cmd.CombinedOutput()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", stdoutStderr)
}

func (*Cmd) Output(显示源文件)

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

输出运行该命令并返回其标准输出。任何返回的错误通常都是 * ExitError 类型。如果 c.Stderr 为零,则输出填充 ExitError.Stderr 。

package main

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

func main() {
	out, err := exec.Command("date").Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("The date is %s\n", out)
}

func (*Cmd) Run(显示源文件)

func (c *Cmd) Run() error

运行开始指定的命令并等待它完成。

如果命令运行,则返回的错误为零,在复制 stdin,stdout 和 stderr 时没有问题,并以零退出状态退出。

如果该命令启动但未成功完成,则错误类型为 * ExitError 。其他错误类型可能会返回其他情况。

package main

import (
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("sleep", "1")
	log.Printf("Running command and waiting for it to finish...")
	err := cmd.Run()
	log.Printf("Command finished with error: %v", err)
}

func (*Cmd) Start(显示源文件)

func (c *Cmd) Start() error

开始启动指定的命令,但不等待它完成。

一旦命令退出,Wait 方法将返回退出代码并释放相关资源。

package main

import (
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("sleep", "5")
	err := cmd.Start()
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Waiting for command to finish...")
	err = cmd.Wait()
	log.Printf("Command finished with error: %v", err)
}

func (*Cmd) StderrPipe(显示源文件)

func (c *Cmd) StderrPipe() (io.ReadCloser, error)

当命令启动时,StderrPipe 将返回一个将连接到命令标准错误的管道。

等待会在看到命令退出后关闭管道,因此大多数呼叫者不需要关闭管道; 但是,含义是在从管道读取完成之前调用 Wait 是不正确的。出于同样的原因,在使用 StderrPipe 时使用 Run 是不正确的。查看 StdoutPipe 示例了解惯用用法。

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("sh", "-c", "echo stdout; echo 1>&2 stderr")
	stderr, err := cmd.StderrPipe()
	if err != nil {
		log.Fatal(err)
	}

	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}

	slurp, _ := ioutil.ReadAll(stderr)
	fmt.Printf("%s\n", slurp)

	if err := cmd.Wait(); err != nil {
		log.Fatal(err)
	}
}

func (*Cmd) StdinPipe(显示源文件)

func (c *Cmd) StdinPipe() (io.WriteCloser, error)

当命令启动时,StdinPipe 返回一个将连接到命令标准输入的管道。在 Wait 看到命令退出后,管道将自动关闭。呼叫者只需调用 Close 即可更快地关闭管道。例如,如果正在运行的命令在标准输入关闭之前不会退出,则调用者必须关闭管道。

package main

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

func main() {
	cmd := exec.Command("cat")
	stdin, err := cmd.StdinPipe()
	if err != nil {
		log.Fatal(err)
	}

	go func() {
		defer stdin.Close()
		io.WriteString(stdin, "values written to stdin are passed to cmd's standard input")
	}()

	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", out)
}

func (*Cmd) StdoutPipe(显示源文件)

func (c *Cmd) StdoutPipe() (io.ReadCloser, error)

当命令启动时,StdoutPipe 返回一个将连接到命令标准输出的管道。

等待会在看到命令退出后关闭管道,因此大多数呼叫者不需要关闭管道; 但是,含义是在从管道读取完成之前调用 Wait 是不正确的。出于同样的原因,使用 StdoutPipe 时调用 Run 是不正确的。查看习惯用法的例子。

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("echo", "-n", `{"Name": "Bob", "Age": 32}`)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}
	var person struct {
		Name string
		Age  int
	}
	if err := json.NewDecoder(stdout).Decode(&person); err != nil {
		log.Fatal(err)
	}
	if err := cmd.Wait(); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s is %d years old\n", person.Name, person.Age)
}

func (*Cmd) Wait(显示源文件)

func (c *Cmd) Wait() error

等待等待命令退出并等待任何复制到标准输入或从标准输出或标准错误复制完成。

该命令必须由 Start 启动。

如果命令运行,则返回的错误为零,在复制 stdin,stdout 和 stderr 时没有问题,并以零退出状态退出。

如果该命令无法运行或未成功完成,则错误类型为 * ExitError 。其他错误类型可能会返回 I/O 问题。

如果 c.Stdin 不是 * os.File,则 Wait 还会等待从 c.Stdin 复制到流程的标准输入的 I/O 循环完成。

等待释放与 Cmd 相关的任何资源。

type Error(显示源文件)

错误记录了未能执行的二进制文件的名称及其失败的原因。

type Error struct {
        Name string
        Err  error
}

func (*Error) Error(显示源文件)

func (e *Error) Error() string

type ExitError(显示源文件)

ExitError 通过命令报告不成功的退出。

type ExitError struct {
        *os.ProcessState

        // Stderr holds a subset of the standard error output from the
        // Cmd.Output method if standard error was not otherwise being
        // collected.
        //
        // If the error output is long, Stderr may contain only a prefix
        // and suffix of the output, with the middle replaced with
        // text about the number of omitted bytes.
        //
        // Stderr is provided for debugging, for inclusion in error messages.
        // Users with other needs should redirect Cmd.Stderr as needed.
        Stderr []byte
}

func (*ExitError) Error(显示源文件)

func (e *ExitError) Error() string
Go

Go 是一种编译型语言,它结合了解释型语言的游刃有余,动态类型语言的开发效率,以及静态类型的安全性。它也打算成为现代的,支持网络与多核计算的语言。要满足这些目标,需要解决一些语言上的问题:一个富有表达能力但轻量级的类型系统,并发与垃圾回收机制,严格的依赖规范等等。这些无法通过库或工具解决好,因此Go也就应运而生了。

主页 https://golang.org/
源码 https://go.googlesource.com/go
发布版本 1.9.2

Go目录

1.档案 | archive
2.缓冲区 | bufio
3.内置 | builtin
4.字节 | bytes
5.压缩 | compress
6.容器 | container
7.上下文 | context
8.加密 | crypto
9.数据库 | database
10.调试 | debug
11.编码 | encoding
12.错误 | errors
13. expvar
14.flag
15. fmt
16. go
17.散列 | hash
18.html
19.图像 | image
20.索引 | index
21.io
22.日志 | log
23.数学 | math
24. math/big
25.math/bits
26.math/cmplx
27.math/rand
28.拟态 | mime
29.net
30.net/http
31. net/mail
32. net/rpc
33.net/smtp
34. net/textproto
35. net/url
36.os
37.路径 | path
38.插件 | plugin
39.反射 | reflect
40.正则表达式 | regexp
41.运行时 | runtime
42.排序算法 | sort
43.转换 | strconv
44.字符串 | strings
45.同步 | sync
46.系统调用 | syscall
47.测试 | testing
48.文本 | text
49.时间戳 | time
50.unicode
51.不安全性 | unsafe
52.Go 语言数据类型
53.Go 语言基础语法
54.Go 语言结构
55.Go 语言 select 语句
56.Go 语言 switch 语句
57.Go 语言 if 语句嵌套
58.Go 语言 if…else 语句
59.Go 语言 if 语句
60.Go 语言运算符
61.Go 语言常量
62.Go 语言函数闭包
63.Go 语言函数作为实参
64.Go 语言函数引用传递值
65.Go 语言函数值传递值
66.Go 语言函数
67.Go 语言 goto 语句
68.Go 语言 continue 语句
69.Go 语言 break 语句
70.Go 语言循环嵌套
71.Go 语言 for 循环
72.Go 语言结构体
73.Go 语言指针作为函数参数
74.Go 语言指向指针的指针
75.Go 语言指针数组
76.Go 语言指针
77.Go 语言向函数传递数组
78.Go 语言多维数组
79.Go 语言变量作用域
80.Go 语言函数方法
81.Go 错误处理
82.Go 语言接口
83.Go 语言类型转换
84.Go 语言递归函数
85.Go 语言Map(集合)
86.Go 语言范围(Range)
87.Go 语言切片(Slice)
88.Go 并发
89.Go fmt.Sprintf 格式化字符串