为什么我的 stderr 重定向在命令完成后没有结束?我该如何解决? [英] Why doesn't my stderr redirection end after command finishes? And how do I fix it?

查看:30
本文介绍了为什么我的 stderr 重定向在命令完成后没有结束?我该如何解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In Windows, either in command line or a batch file, the command DIR 2>NUL: 3>&2 (you can replace DIR with anything, even if isn't a file or a command) will make all errors from then on missing unless you write 2>CON: after every command. Why is CMD even doing this? And how do you get it back to normal without starting a new CMD process? DIR 2>CON: 3>&2 will only work for that command alone.

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

This will work with files as well. DIR 2>TEXT.TXT 3>&2 Any errors after that will be appended to the file.

推荐答案

这是一个重现您所看到的问题的测试脚本.

Here is a test script that reproduces the problem you are seeing.

@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 外壳也是如此.

stderr (stream 2) has been disabled "permanently", even for the parent CMD.EXE shell.

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

You can avoid the "permanent" aspect by doing your redirection in stages:

@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

I don't really understand what is going on. But I have done some interesting experiments. Check out this thread: http://www.dostips.com/forum/viewtopic.php?f=3&t=2836&start=30

附录

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

As Erbert has discovered and shared in his comment, the fix is even easier if you just switch the order of the redirection - no need to stage it.

@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 文档未定义).

Update 2012-04-03 I believe I finally understand the mechanics of Windows CMD.EXE redirection. I have a working theory that fully accounts for all the weird behavior, including why reversing the order prevents the "permanent" redirection. It also explains Aacini's observation that handle 3 appears to be connected to CON: (It isn't, it is actually undefined as per Windows documentation).

关键点是:

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

1 - Whenever a handle (stream) is redirected, the original definition is transferred to the first available undefined handle. Successive redirections are always carried out from left to right.

2 - 重定向结束后,通常会恢复原始定义.但是,如果存在一连串重定向,则恢复仅在 1 级深度进行.这是永久"重定向的来源.

2 - When the redirection is over, the original definitions are normally restored. But if there is a chain of redirections, then the restoration is only done 1 level deep. This is the source of the "permanent" redirection.

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

Edit 2014-12-19: Put another way, the restoration appears to be done using a queue structure (FIFO - First In First Out), when it should have been implemented as a stack (LIFO - Last In First Out).

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

3 - When CMD.EXE carries out the redirection, it saves the current definition in the undefined handle first, then it redirects the first handle. If the first handle is redirected to the originally undefined handle, then it is effectively redirected to its original definition! That is why echo hello 1>&3 outputs to the console.

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

The full theory and test cases are available in two consecutive posts at http://www.dostips.com/forum/viewtopic.php?p=14612#p14612.

这篇关于为什么我的 stderr 重定向在命令完成后没有结束?我该如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆