
在 Go 中直接通过 exec.Command("echo", "...", ">", "file.txt") 无法实现 Shell 重定向,因为 > 是 Shell 特性,而 exec.Command 默认不经过 Shell 解析;需手动创建文件并设置 cmd.Stdout 才能将命令输出写入文件。
在 go 中直接通过 `exec.command("echo", "...", ">", "file.txt")` 无法实现 shell 重定向,因为 `>` 是 shell 特性,而 `exec.command` 默认不经过 shell 解析;需手动创建文件并设置 `cmd.stdout` 才能将命令输出写入文件。
Go 的 os/exec 包设计为绕过 Shell执行命令,以提升安全性与可预测性。这意味着像 >, |, &&, $VAR 等 Shell 内建语法不会被识别或处理——你传入的 "\"foo 0x50\"", ">", "test.txt" 会被当作三个独立参数传递给 echo 程序本身,最终实际执行的是:
echo '"foo 0x50"' '>' 'test.txt'
这会导致 echo 直接打印三个字符串(含引号和 > 符号)到标准输出,而不会触发任何重定向行为,因此 test.txt 自然不会被创建。
✅ 正确做法是:显式创建目标文件,并将 cmd.Stdout 指向该文件句柄。以下是推荐的完整实现(含错误处理与资源管理):
Echo框架 5.1.0 版本源码包下载,适合关注 RealIP 行为变化、StartConfig.Listener、NewDefaultFS 和观测性中间件入口的开发团队。
package main
import (
"fmt"
"os"
"os/exec"
)
func main() {
// 构造 echo 命令:注意——无需手动加外层引号
// Go 会自动按参数边界传递,"foo 0x50" 将作为单个参数传给 echo
cmd := exec.Command("echo", "foo 0x50")
// 创建/截断文件(等效于 > test.txt)
file, err := os.Create("test.txt")
if err != nil {
fmt.Printf("无法创建文件: %v\n", err)
return
}
defer file.Close() // 确保文件及时关闭
// 关键:将命令的标准输出重定向到文件
cmd.Stdout = file
// 启动并等待命令完成
if err := cmd.Run(); err != nil { // Run() = Start() + Wait(),更简洁
fmt.Printf("命令执行失败: %v\n", err)
return
}
fmt.Println("✅ 'foo 0x50' 已成功写入 test.txt")
}? 关键说明与注意事项:
-
exec.Command("echo", "foo 0x50")会准确输出foo 0x50(无额外引号);若你确实需要字面量双引号(即文件内容为"foo 0x50"),应写作exec.Command("echo","foo 0x50")—— Go 字符串中的反引号或转义双引号会被原样传递。 - 使用
cmd.Run()替代cmd.Start()+cmd.Wait()更安全、简洁,它会自动等待进程结束并返回退出状态错误。 -
os.Create()会清空已有文件内容(类似>),如需追加,请改用os.OpenFile(..., os.O_APPEND|os.O_CREATE|os.O_WRONLY)。 - 避免调用
/bin/sh -c "echo ... > file"来模拟 Shell 行为——虽可行但引入 Shell 依赖、安全隐患(如命令注入)及平台差异,违背 Go 的显式设计哲学。
通过这种显式 I/O 重定向方式,你不仅能精准控制输出目标,还能统一处理错误、超时、管道等高级场景,这才是 Go 生态中执行外部命令的惯用且健壮的做法。

















