流式传输 os/exec.Command

streaming os/exec.Command

我想构建一个类似于 unix 工具的基准测试工具 time。我目前拥有的是:

package main

import (
    "fmt"
    "os"
    "os/exec"
    "time"
)

func main() {
    command := os.Args[1]
    args := os.Args[2:]
    cmd := exec.Command(command, args...)
    start_time := time.Now().UnixNano()
    stdout, err := cmd.Output()

    if err != nil {
        println(err.Error())
        return
    }

    print(string(stdout))
    total_time := int64(time.Nanosecond) * (time.Now().UnixNano() - start_time) / int64(time.Millisecond)
    fmt.Println(total_time)
}

我的问题是,输出不是流式的,而是一次全部打印出来的,奇怪的是有些程序根本不输出。

最好的方法是完全避免接触流。您可以直接为 stdout 和 stderr 传递自己的文件描述符。

package main

import (
    "fmt"
    "os"
    "os/exec"
    "time"
)

func main() {
    command := os.Args[1]
    args := os.Args[2:]
    cmd := exec.Command(command, args...)
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    start_time := time.Now()

    err := cmd.Run()
    if err != nil {
        println(err.Error())
        return
    }

    total_time := int64(time.Since(start_time) / time.Millisecond)
    fmt.Println(total_time)
}

此外,切勿使用 print()。相反,使用 fmt.Print* 函数之一。


total_time := int64(time.Nanosecond) * (time.Now().UnixNano() - start_time) / int64(time.Millisecond)

这一行非常混乱。 int64(time.Nanosecond) * x 解析为 1 * x 或只是 x.

我不确定你在这里试图用 print(string(stdout)) 做什么,但这是不必要的,你面临的问题可能是那里的一些误用的副作用。

func main() {
    command := os.Args[1]
    args := os.Args[2:]
    cmd := exec.Command(command, args...)
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    start_time := time.Now().UnixNano()

    if err != nil {
        fmt.Println(err.Error())
        return
    }

    total_time := int64(time.Nanosecond) * (time.Now().UnixNano() - start_time) / int64(time.Millisecond)
    fmt.Println(total_time)
}