windows - 为什么我的 stderr 重定向在命令完成后没有结束?我该如何解决?

标签 windows command-line batch-file cmd

在 Windows 中,无论是在命令行还是批处理文件中,命令 DIR 2>NUL: 3>&2(您可以将 DIR 替换为任何内容,即使不是'一个文件或命令)将使所有错误从那时起丢失,除非你在每个命令后写 2>CON:。为什么 CMD 甚至要这样做?以及如何在不启动新的 CMD 进程的情况下使其恢复正常? DIR 2>CON: 3>&2 仅适用于该命令。

编辑:这也适用于文件。 DIR 2>TEXT.TXT 3>&2 之后的任何错误都将附加到文件中。

最佳答案

这是一个重现您遇到的问题的测试脚本。

@echo off
2>nul 3>nul (
  echo I want to see stream1
  1>&2 echo I don't want to see this stream2
  1>&3 echo I don't want to see this stream3
)
echo stream1 works fine
1>&2 echo stream2 is now "permanently" void. I don't see this.
1>&3 echo stream3 works fine

这是输出

I want to see stream1
stream1 works fine
stream3 works fine

stderr(流 2)已“永久”禁用,即使对于父 CMD.EXE shell。

您可以通过分阶段进行重定向来避免“永久”方面:

@echo off
2>nul (
  3>nul (
    echo I want to see stream1
    1>&2 echo I don't want to see this stream2
    1>&3 echo I don't want to see this stream3
  )
)
echo stream1 works fine
1>&2 echo stream2 works fine
1>&3 echo stream3 works fine

这是期望的输出:

I want to see stream1
stream1 works fine
stream2 works fine
stream3 works fine

我不太明白这是怎么回事。但是我做了一些有趣的实验。查看此线程:http://www.dostips.com/forum/viewtopic.php?f=3&t=2836&start=30

附录

正如 Erbert 发现并在他的评论中分享的那样,如果您只是切换重定向的顺序,则修复会更容易 - 无需暂存。

@echo off
3>nul 2>nul (
  echo I want to see stream1
  1>&2 echo I don't want to see this stream2
  1>&3 echo I don't want to see this stream3
)
echo stream1 works fine
1>&2 echo stream2 works fine
1>&3 echo stream3 works fine

更新 2012-04-03 我相信我终于理解了 Windows CMD.EXE 重定向的机制。我有一个工作理论可以完全解释所有奇怪的行为,包括为什么颠倒顺序会阻止“永久”重定向。它还解释了 Aacini 的观察,即句柄 3 似乎连接到 CON:(实际上不是,根据 Windows 文档,它实际上是未定义的)。

关键点是:

1 - 每当句柄(流)被重定向时,原始定义被转移到第一个可用的未定义句柄。连续的重定向总是从左到右执行。

2 - 重定向结束后,通常会恢复原来的定义。但是,如果存在重定向链,则仅在 1 级深度进行恢复。这是“永久”重定向的来源。

编辑 2014-12-19:换句话说,恢复似乎是使用队列结构(FIFO - 先进先出)完成的,而它本应作为堆栈实现( LIFO - 后进先出)。

3 - CMD.EXE 执行重定向时,首先将当前定义保存在未定义的句柄中,然后重定向第一个句柄。如果第一个句柄被重定向到最初未定义的句柄,那么它实际上被重定向到它的原始定义!这就是 echo hello 1>&3 输出到控制台的原因。

完整的理论和测试用例可以在 http://www.dostips.com/forum/viewtopic.php?p=14612#p14612 的两个连续帖子中找到。 .

关于windows - 为什么我的 stderr 重定向在命令完成后没有结束?我该如何解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9878007/

相关文章:

windows - Web Deploy (MSDeploy) 3.6 替换规则重命名文件

windows - if/else 将输出重定向到批处理文件中的空变量

c++ - Windows上的封包记录

bash - 调用 readline 绑定(bind)命令后刷新 Bash 提示符

python - Windows 如何将 pe 文件链接到它在目录文件中的签名?

c# - 当我使用 Control-C 中断 C# 控制台应用程序时会发生什么?

windows - 使Windows批处理文件在程序退出时不关闭

sql - 如何使用 CLP 将值从 bat 文件传递​​到 DB2 sql 文件

c# - 如何设置扬声器声音增强设置

windows - 为 x64 和 x86(并行安装)构建 OpenSSL?