【问题标题】:streaming os/exec.Command流式操作系统/exec.Command
【发布时间】:2015-06-26 20:13:04
【问题描述】:

我想构建一个类似于 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)
}

我的问题是,输出不是流式传输,而是一次全部打印出来,而且对于某些程序来说,这很奇怪。

【问题讨论】:

    标签: shell go stream stdout


    【解决方案1】:

    最好的方法是完全避免接触流。您可以直接为 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

    【讨论】:

    • OP 可能看到时间 * x 在 x 为 int 类型时不起作用。没有理由total_time := int64(...
    • 我是说将它乘以纳秒是无操作的,因为纳秒 = 1。
    • 感谢您的所有建议,我是新手,主要是从不同来源复制和粘贴内容。
    • 纳秒的东西来源于这个线程中的 cmets stackoverflow.com/questions/24122821/…
    • 其实,nvm。由于各种原因,我之前的建议是错误的。
    【解决方案2】:

    我不确定您在此处尝试使用 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)
    }
    

    【讨论】:

    • OP 希望看到命令的输出通过管道传输到 stdout 和 stderr。
    • @DanverBraganza 这是一个简单的更改,我会编辑它。
    猜你喜欢
    • 1970-01-01
    • 2018-07-11
    • 2016-10-21
    • 2015-07-16
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-05
    相关资源
    最近更新 更多