exec

1 os/exec包

​特性​

os/exec 包​

​系统 Shell (如 Bash)​

​命令解析​

直接执行二进制文件,无参数扩展

自动展开通配符、变量替换、管道等

​安全性​

无隐式解析,避免注入风险

需谨慎处理用户输入,易受注入攻击

​资源消耗​

轻量级,无额外 Shell 进程开销

需要启动 Shell 进程,增加开销

​跨平台一致性​

行为一致,适合跨平台代码

依赖宿主 Shell,行为可能不一致

os/exec包不是直接调用系统shell,也不拓展任何glob模式或处理通常由shell完成的其他扩展、管道或重定向。要扩展glob模式请直接调用 shell,注意转义任何危险的输入,或使用 path/filepatharrow-up-right 包的 Glob 函数。

2 LookPath

LookPath 函数用于在系统的 ​​PATH 环境变量​​中查找可执行文件的绝对路径。默认不会带

  • ​功能​​:在系统的 PATH 环境变量中搜索指定命令的绝对路径。

  • ​用途​​:

    • 验证命令是否存在。

    • 获取可执行文件的完整路径(避免直接依赖 PATH 顺序)。

  • ​底层行为​​:

    • ​Windows​​:自动尝试添加 .exe.bat 等扩展名。

    • ​Unix/Linux​​:直接匹配文件名(需文件有可执行权限)。

exec.Command内部自动调用LookPath解析命令,但命令不存在的错误将在 cmd.Run 才抛出。

3 Cmd类型

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

  1. ​字段分类​

    • ​必须字段​​:Path 是唯一必须设置的字段。

    • ​输入/输出控制​​:StdinStdoutStderr 管理进程的 I/O 流。

    • ​高级控制​​:SysProcAttrExtraFiles 处理平台相关逻辑。

    • ​生命周期管理​​:ProcessProcessState 提供进程运行时和退出后的信息。

  2. ​线程安全​

    • ​不可变性​​:调用 Start()Run()Output() 后,禁止并发修改字段。

  3. ​跨平台行为​

    • ​路径解析​​:Path 在 Windows 中自动尝试 .exe.bat 等扩展名。

    • ​环境变量​​:Windows 自动处理 SYSTEMROOT,Unix 严格检查文件权限。

  4. ​错误处理​

    • ​提前验证​​:通过 LookPath 检查 Path 有效性(见 Err 字段)。

    • ​超时控制​​:结合 CommandContextWaitDelay 防止僵尸进程。

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

  • 作用​​:创建表示外部命令的 Cmd 对象。

  • ​关键点​​:

    • name 为可执行文件路径或系统 PATH 中的命令名。

    • arg 为参数列表(需拆分,避免直接传递字符串拼接的命令)。

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

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

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

  • 作用:跟Command类似,但包含上下文。

  • 关键点

    • 提供的上下文用于中断进程

    • CommandContext 将命令的 Cancel 函数设置为在其 Process 上调用 Kill 方法,并未设置其 WaitDelay。调用方可以通过在启动命令之前修改这些字段来更改取消行为。

3.3 (c)Run() error

作用​​:启动命令并等待其完成(同步执行)。 ​​返回值​​:命令退出状态错误(若命令返回非零状态码,返回 ExitError)。

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

3.4 (c)Start() error

作用​​:异步启动命令(不等待完成)。 ​​典型用法​​:配合 Wait() 实现异步执行。

3.5 (c)Wait() error

作用​​:等待由 Start() 启动的命令完成。 ​​注意​​:必须在 Start() 后调用,否则返回错误。

3.6 (c)Output() ([]byte, error)

作用​​:执行命令并捕获其标准输出。 ​​等价于​​:Run() + 捕获 Stdout

3.7 (c)CombinedOutput() ([]byte, error)

作用​​:执行命令并捕获标准输出 + 标准错误的合并结果。 ​​适用场景​​:需要同时获取正常和错误输出。

3.8 (c)StdinPipe() (io.WriteCloser, error)

作用​​:获取命令的标准输入管道,用于向命令传递数据。 ​​流程​​:

  1. 调用 StdinPipe() 获取写入器。

  2. Start() 后向管道写入数据。

  3. 关闭管道以通知命令输入结束。

最后更新于