cmd.Run()仅返回执行结果而不捕获输出,cmd.Output()自动捕获stdout但stderr仍输出到终端;需同时捕获两路输出时应分别设置Stdout/Stderr为bytes.Buffer并调用Run()。
cmd.Run() 和 cmd.Output() 的核心区别在哪
用
只能知道命令是否成功退出,拿不到 stdout/stderr 内容;而
会自动捕获 stdout,但 stderr 仍会直接打印到终端——这常导致日志混乱或误判失败原因。
:适合只关心执行结果(如启停服务),不需读取输出
:适合命令预期成功且 stdout 是主数据(如
),但 stderr 未被捕获,错误时可能静默失败
真正需要同时处理两路输出时,必须手动设置
和
为
或其他
如何安全捕获 stdout 和 stderr 并区分它们
别依赖
——它把两路流混在一起,无法判断哪行是 error、哪行是正常输出。正确做法是分别绑定缓冲区,再按需解析。
用两个
实例,分别赋给
和
调用
后,再从两个 buffer 中读取字符串:
、
注意:如果命令输出很大,
会吃内存;高频/大输出场景建议用
配合 goroutine 流式处理
示例关键片段:
exec.Command() 启动的进程没结束,程序就退出了怎么办
常见于后台命令(如
、
)被父进程忽略生命周期管理,导致子进程变成孤儿或被系统回收。
默认情况下,Go 进程退出时,子进程不一定终止——取决于操作系统信号传递和进程组设置
加
可让子进程独立成组,避免意外继承信号
更稳妥的是显式控制生命周期:用
或
在 defer 或 context cancel 时清理
若需等待子进程自然退出,别漏掉
,否则可能残留僵尸进程(尤其在循环启动多命令时)
跨平台命令路径和参数空格问题怎么避坑
Windows 下用
,Linux/macOS 用
——硬写字符串拼接极易出错;更麻烦的是带空格的路径或参数,比如
。
go语言参考手册 中文CHM版
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译
下载
立即学习
“
go语言免费学习笔记(深入)
”;
永远不要用
拼接用户输入,有 shell 注入风险
路径含空格时,
第一个参数必须是完整可执行文件路径,后续参数单独传,Go 会自动处理转义,例如:
需要 shell 功能(管道、重定向)时,封装一层函数统一处理平台差异,而不是每个地方 if/else 判定
用
查找命令位置,比硬编码
或
更健壮
最常被跳过的其实是错误码语义:非零退出码不等于 panic,也不等于
就一定失败——有些工具(如
)用退出码表达业务逻辑,得自己检查
。
cmd.Run()cmd.Output()cmd.Run()cmd.Output()git rev-parse HEADcmd.Stdoutcmd.Stderrbytes.Bufferio.Writercmd.CombinedOutput()bytes.Buffercmd.Stdoutcmd.Stderrcmd.Run()stdoutBuf.String()stderrBuf.String()bytes.Bufferio.PipestdoutBuf := &bytes.Buffer{}
stderrBuf := &bytes.Buffer{}
cmd.Stdout = stdoutBuf
cmd.Stderr = stderrBuf
err := cmd.Run()
// err 不为 nil 时,stderrBuf.String() 往往含真实错误信息tail -fpython -m http.servercmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}cmd.Process.Kill()cmd.Process.Signal(syscall.SIGTERM)cmd.Wait()exec.Command("cmd", "/c", "echo hello")exec.Command("sh", "-c", "echo hello")"C:Program Filescurlcurl.exe"exec.Command("sh", "-c", "some command with $VAR")exec.Commandexec.Command("C:\Program Files\curl\curl.exe", "-s", "https://api.example.com")exec.LookPath()"ls""dir"error != nilgrepcmd.ProcessState.ExitCode()