Go中执行外部命令需正确使用exec.Command:Run()适合无需输出的场景;Output()一行获取stdout;Stdin/Stdout/Stderr管道实现细粒度控制;须防shell注入、设超时、控环境变量与工作目录。
使用 os/exec 包执行外部命令是 Go 中很常见的需求,核心在于正确创建、配置并运行 *exec.Cmd 实例。关键不是“能不能跑”,而是“怎么控制输入输出、捕获错误、避免阻塞、防止 shell 注入”。
Run() 适合不需要读取输出、只关心命令是否成功的情况(比如 git commit、cp)。
error(非零退出码也会转为 error)示例:
```goOutput() 自动重定向 stdout 到内存,返回 []byte 和 error,适合简单命令如 date、hostname、cat file。
find / | head -1000 类命令示例:
```go当需要实时处理流、双向通信、或分别捕获 stdout/stderr 时,用 StdinPipe、StdoutPipe、StderrPipe。
Start() 前调用 Pipe 方法,否则 panicStart() 启动命令但不等待,之后可读写管道、再调用 Wait()
bytes.Buffer 或 io.MultiWriter 收集输出示例(捕获 stdout + stderr 分开):
```go
stderr:", stderr.String()) // "world\n"绕不开的几个实际问题:
exec.Command("grep", "-r", userInput, "."),而不是 exec.Command("sh", "-c", "grep -r '"+userInput+"' .")
context.WithTimeout 传给 CommandContext,比手动 goroutine + timer 更可靠cmd.Env 可覆盖或添加环境变量(默认继承 os.Environ)cmd.Dir 指定执行路径带超时的完整示例:
```go基本上就这些。用对 Run/Output/Start+Wait 三种模式,再注意安全和超时,90% 的外部命令需求都能稳稳拿下。