【问题标题】:Does stdout get stored somewhere in the filesystem or in memory? [duplicate]stdout 是否存储在文件系统或内存中的某个位置? [复制]
【发布时间】:2013-12-31 21:17:18
【问题描述】:

我知道我可以使用last_output=$(my_cmd) 将命令的结果保存到变量中,但我真正想要的是每次运行命令时$last_output 都会得到更新。是否有可以安装的变量、zsh 模块或插件?

我想我的问题是stdout 是否被永久写入某处(至少在下一个命令之前)?这样我就可以操纵前一个命令的结果,而不必重新运行它。这对于需要很长时间运行的命令非常有用

【问题讨论】:

  • stdout 只是一个文件句柄,默认情况下连接到控制台,但可以重定向。如果需要,您可以重定向输出以存储在文件中,然后在显示结果之前操作该文件。
  • 如果我这样做会丢失控制台输出吗?我可以将其重定向到两者吗?
  • 您不能在没有开销或副作用的情况下直接重定向到两个地方——每次write() 调用只能将输出输出到一个目的地——但您可以重定向到诸如tee 之类的进程依次写入两个地方。

标签: shell stdout zsh


【解决方案1】:

如果您运行以下命令:

exec > >(tee save.txt)
# ... stuff here...
exec >/dev/tty

...那么您在两个命令之间运行的所有内容的标准输出都将发送到标准输出和save.txt

当然,您可以编写一个 shell 函数来为您执行此操作:

with_saved_output() {
  "$@" \
  2> >(tee "$HOME/.last-command.err >&2) \
  | tee "$HOME/.last-command.out"
}

...然后随意使用:

with_saved_output some-command-here

...zsh 几乎肯定会提供一种机制来包装交互式输入的命令。 (在 bash 中,我可以更直接地说,你可以用 DEBUG 陷阱做同样的事情。


但是,即使您可以,您不应该这样做:当您将 stdout 和 stderr 分成两个流时,有关写入的确切顺序的信息会丢失,即使这些流稍后重新组合。

因此,输出

O: this is written to stdout first
E: this is written to stderr second

可能变成:

E: this is written to stderr second
O: this is written to stdout first

当这些流单独通过tee 子进程以将副本写入磁盘时。还会产生缓冲问题,以及由检查是否输出到 TTY 并更改其行为的软件引起的行为差异(例如,软件在直接写入控制台时打开颜色编码输出,在写入时关闭文件或管道)。

【讨论】:

    【解决方案2】:

    stdout 只是一个文件句柄,默认情况下连接到控制台,但可以重定向。

    yourcommand > save.txt
    

    如果您想将输出显示到控制台并同时将其保存到文件中,您可以将输出通过管道传输到 tee,该命令将接收到的所有内容写入 stdin stdout 和您选择的文件:

    yourcommand | tee save.txt
    

    【讨论】:

    • 是的,但是有没有办法使这种可持续发展?关键是我有时运行的命令比我想象的要长,我不想再次运行它来操纵输出
    • 通过使用内置命令 execin zsh exec > >(tee ~/save.txt),您将在显示到控制台的同时将所有输出保存到文件 save.txt 中。但是,save.txt 将包含所有输出,而不仅仅是来自最后一个命令。我不知道有一种方法可以为每个命令执行此操作,而不是在运行每个命令时指定它。
    • 对不起,上面缺少空格,exec 周围的 ** 是为了使其粗体:exec 但由于最后一个 * 之后缺少空格,因此未翻译星号。
    猜你喜欢
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多