当前位置: 首页 > 面试题库 >

在实时输出时,如何将命令的stdout和stderr重定向到控制台和日志文件?

景同
2023-03-14
问题内容

下面的代码完全符合我的要求,只将其打印到控制台。

cmd := exec.Command("php", "randomcommand.php")

cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

if err := cmd.Run(); err != nil {
    log.Fatal(err)
}

randomcommand.php:

// randomcommand.php simply alternates output between stdout and stderr 20 times

$stdout = fopen('php://stdout', 'w+');
$stderr = fopen('php://stderr', 'w+');
for ($i = 1;$i <= 20; $i++) {
    fwrite($stdout, "stdout $i\n");
    fwrite($stderr, "stderr $i\n");
}

输出:

stdout 1
stderr 1
stdout 2
stderr 2
stdout 3
stderr 3
stdout 4
stderr 4
stdout 5
stderr 5
stdout 6
stderr 6
stdout 7
stderr 7
stdout 8
stderr 8
stdout 9
stderr 9
stdout 10
stderr 10
stdout 11
stderr 11
stdout 12
stderr 12
stdout 13
stderr 13
stdout 14
stderr 14
stdout 15
stderr 15
stdout 16
stderr 16
stdout 17
stderr 17
stdout 18
stderr 18
stdout 19
stderr 19
stdout 20
stderr 20

我想要实现的是:

  1. 实时将命令的stdout和stderr打印到控制台;
  2. 将命令的stdout和stderr记录到文件中,该文件与控制台中显示的完全相同。
  3. 尊重写到stdout和stderr的确切顺序,并且;
  4. 不修改命令本身

我试过将stdout和stderr命令传递到扫描仪中或使用io.Copy,它们分别在goroutine中进行,但是未维护输出顺序。可能是因为goroutine之间的交替必须在输出交替的同时发生,这几乎是不可能的。

我也尝试过使用“中选择”作为从例子在这里。但是没有保持输出顺序。

Logstreamer也存在同样的问题。

我必须尝试的另一个想法是看看是否可以从控制台缓冲区中读取内容,但这感觉不对。

有谁知道这是否有可能并且值得追求?


问题答案:

正如我在评论部分中所述,可以使用MultiWriter来实现

package main

import (
    "io"
    "log"
    "os"
    "os/exec"
)

func main() {
    // Logging capability
    f, err := os.OpenFile("log.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
    if err != nil {
        log.Fatalf("Error opening file: %v", err)
    }
    defer f.Close()
    mwriter := io.MultiWriter(f, os.Stdout)
    cmd := exec.Command("ls")
    cmd.Stderr = mwriter
    cmd.Stdout = mwriter
    err = cmd.Run() //blocks until sub process is complete
    if err != nil {
        panic(err)
    }
}

在声明命令时以及在运行命令之前,只需指定Stdout和Stderr使用上面定义的MultiWriter。该MultiWriter实例包含一个日志文件和标准输出。



 类似资料:
  • 我有一个调用函数的PowerShell脚本。我正在努力实现所有这些,但不确定如何实现: 将标准输出写入控制台并输出。txt 将STDERR写入控制台并输出。txt和err。txt 确保所有STDOUT和STDERR输出仍按其生成的顺序 这就是我到目前为止所拥有的将STDOUT和STDERR写入文件的功能,但它不能完成我需要的其余部分。

  • 我想将stdout和stderr重定向到一个文件,同时保留输出顺序,然后还将stderr显示到屏幕上。我看到很多问题讨论它: https://unix.stackexchange.com/questions/9646/show-only-stderr-on-screen-but-write-both-stdout-and-stderr-to-file https://unix.stackexcha

  • 在Pycharm上,我有一些长时间的测试,我希望能够手动监控。 像神经网络训练这样的事情的进度--我希望看到损失和进度条。 我找到了这个答案,并尝试了和,它们基本上什么都不做。 2021年2月3日刚刚在Pycharm的论坛上被问到。

  • 问题语句:我有一个在Xcode中运行的程序,它有一堆print()语句,可以很好地将输出打印到调试控制台。然而,我希望也能够将这些输出重定向到一个文件,这样我就可以让用户将它们发送给我,作为调试的一种方式。 SO上找到的解决方案使我可以将输出重定向到文件,但调试控制台输出将丢失。 问:我想要我的蛋糕和吃它。我希望能够将print()语句重定向到调试控制台和文件。 所以我有引用:https://st

  • 问题内容: 我在cyberciti.biz的评论中看到了这个有趣的问题。 我发现我什至找不到在sh的单行命令中执行此操作的灵活方法。 到目前为止,我对解决方案的想法是: 但是您会看到,这不是同步的,而且致命的是,它是如此丑陋。 欢迎与您分享这个想法。:) 问题答案: 你要 这里的顺序很重要。假设stdin(fd 0),stdout(fd 1)和stderr(fd 2)最初都连接到tty,因此 首先

  • 很好的一天。我有一系列的命令,我想通过一个函数来执行,这样我就可以得到退出代码并相应地执行控制台输出。话虽如此,我这里有两个问题: 1) 我似乎无法将stderr指向/dev/null。 2) 在执行$1之前,不会显示第一条回显行。直到我运行需要一段时间才能处理的命令,比如在硬盘上搜索文件,我才真正注意到这一点。此外,情况显然是这样,因为输出如下所示: 换句话说,stderr显示在“尝试…$2”之