gpt4 book ai didi

bash - 如何在不停止写入终端的情况下复制 stderr?

转载 作者:行者123 更新时间:2023-11-29 09:00:09 28 4
gpt4 key购买 nike

我想编写一个运行命令的 shell 脚本,在命令到达时将其 stderr 写入我的终端。但是,我还想将 stderr 保存到一个变量中,以便稍后检查它。

我怎样才能做到这一点?我应该使用 tee、子 shell 还是其他东西?

我已经试过了:

# Create FD 3 that can be used so stdout still comes through 
exec 3>&1

# Run the command, piping stdout to normal stdout, but saving stderr.
{ ERROR=$( $@ 2>&1 1>&3) ; }

echo "copy of stderr: $ERROR"

但是,这不会将 stderr 写入控制台,它只会保存它。

我也试过:

{ $@; } 2> >(tee stderr.txt >&2 )

echo "stderr was:"
cat stderr.txt

但是,我不想要临时文件。

最佳答案

我经常想这样做,并发现自己正在访问 /dev/stderr,但这种方法可能存在问题;例如,Nix如果构建脚本尝试写入 /dev/stdout/dev/stderr,则会出现“权限被拒绝”错误。

在重新发明了几次这个轮子之后,我目前的做法是使用流程替换如下:

myCmd 2> >(tee >(cat 1>&2))

从外到内阅读:

这将运行 myCmd,并保持其标准输出不变。 2> 会将 myCmd 的标准错误重定向到不同的目的地;这里的目的地是 >(tee >(cat 1>&2)),这将导致它被输送到命令 tee >(cat 1>&2)

tee 命令将其输入(在本例中为 myCmd 的标准错误)复制到它的标准输出和给定的目的地。此处的目标是 >(cat 1>&2),这将导致数据通过管道传输到命令 cat 1>&2

cat 命令只是将其输入直接传递到标准输出。 1>&2 将 stdout 重定向到 stderr。

由内而外的阅读:

cat 1>&2 命令将其 stdin 重定向到 stderr,因此 >(cat 1>&2) 的行为类似于 /dev/stderr .

因此 tee >(cat 1>&2) 将其 stdin 复制到 stdout 和 stderr,就像 tee/dev/stderr 一样。

我们使用 2>>(tee >(cat 1>&2)) 得到 2 个 stderr 副本:一个在 stdout 上,一个在 stderr 上。

我们可以正常使用 stdout 上的副本,例如将其存储在变量中。我们可以将副本保留在 stderr 上以打印到终端。

如果我们愿意,我们可以将它与其他重定向结合起来,例如

# Create FD 3 that can be used so stdout still comes through 
exec 3>&1

# Run the command, redirecting its stdout to the shell's stdout,
# duplicating its stderr and sending one copy to the shell's stderr
# and using the other to replace the command's stdout, which we then
# capture
{ ERROR=$( $@ 2> >(tee >(cat 1>&2)) 1>&3) ; }

echo "copy of stderr: $ERROR"

关于bash - 如何在不停止写入终端的情况下复制 stderr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26915448/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com