我编写了一个测试程序来分析今天导致错误的一段代码的行为,以更好地了解其行为。相反的情况发生了。
这是测试程序。它应该执行一个测试命令并将命令输出流式传输到标准输出。
import (
"bufio"
"fmt"
"io"
"os/exec"
)
func main() {
cmd1 := exec.Command("./testcommands/testcommand.sh")
execCmd(cmd1)
cmd2 := exec.Command("./testcommands/testcommand")
execCmd(cmd2)
}
func execCmd(cmd *exec.Cmd) {
stderr, _ := cmd.StderrPipe()
stdout, _ := cmd.StdoutPipe()
multi := io.MultiReader(stdout, stderr)
scanner := bufio.NewScanner(multi)
cmd.Start()
for scanner.Scan() {
m := scanner.Text()
fmt.Println(m)
}
cmd.Wait()
}
调用的两个测试命令基本相同。一种是用bash实现的
#!/bin/bash
for i in `seq 1 10` ; do
echo "run $i"
sleep 1
done
另一个在 C
#include <stdio.h>
#include <unistd.h>
int main() {
int i;
for (i=1; i<=10; i++) {
printf("run %d\n", i);
sleep(1);
}
return 0;
}
shell 脚本的输出确实被流式传输(每秒 1 行),但是 c 程序的输出仅在程序完全完成后才到达(10 秒后一次 10 行)。
这超出了我的脑海。我什至不确定这是否按预期工作,我只是遗漏了一些东西,或者我是否应该打开错误报告 - 如果是这样,我什至不确定它是用于 bash、golang 还是 c . 或者也许这是我不知道的一些 linux 事情。
当stdout
(printf
写入)连接到终端时,stdout
将被行缓冲,并且输出将在每个换行符上刷新(实际写入)。
但是当stdout
没有连接到终端时,例如它用于重定向或管道,那么它就会被完全缓冲。完全缓冲意味着仅当缓冲区变满(在您的小示例中不太可能)或显式刷新(例如使用fflush(stdout)
)时才会写入输出。
Goexec
功能可能做的是为程序输入和输出创建管道。
为了解决您的问题,您的 C 程序需要fflush
在每次printf
调用后调用:
printf("run %d\n", i);
fflush(stdout);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句