如何将主进程stdout捕获到Bash变量,同时让子进程输出直显终端?
解决方案
要实现主进程stdout被Bash变量捕获,同时子进程输出直接打印到终端,核心是让子进程绕过主进程被重定向的stdout,直接输出到终端设备(/dev/tty)。具体修改如下:
修改后的Go代码
package main import ( "fmt" "os" "os/exec" ) func main() { fmt.Println("I want this captured") // 打开终端设备,用于子进程输出 tty, err := os.OpenFile("/dev/tty", os.O_WRONLY, 0) if err != nil { fmt.Printf("Failed to open /dev/tty: %v\n", err) os.Exit(1) } defer tty.Close() // 配置子进程输出到终端 command := exec.Command("ls") command.Stdout = tty command.Stderr = tty if err := command.Run(); err != nil { fmt.Printf("Command failed: %v\n", err) os.Exit(1) } }
原理说明
- 当执行
output=$(go run main.go)时,主进程的os.Stdout会被Bash重定向到管道,最终存入output变量。 - 子进程通过直接写入
/dev/tty(当前终端设备文件),绕过了主进程的stdout重定向,输出会直接显示在终端,不会被$(...)捕获。
测试验证
- 保存修改后的代码为
main.go - 执行命令:
output=$(go run main.go)
此时会直接看到ls的输出打印在终端。
3. 查看捕获的内容:
echo "$output"
只会输出I want this captured,符合预期。
内容的提问来源于stack exchange,提问作者Andre
相关产品推荐
相关产品推荐

