尝试删除(或覆盖)只读文件无法重定向 "STDERR"

Attempted delete (or overwrite) of read-only file fails to redirect "STDERR"

我有一个批处理文件,有时可能需要删除文件(或覆盖现有文件)。我以这样的标准方式执行此操作:

c:\>del somefile

这(在文件为 "read only" 的情况下)当然会导致错误消息:

Access is denied.

在删除命令失败的情况下,我想通过删除后检查文件是否存在来测试是否删除成功。所以,我想将输出(STDOUT)和错误输出(STDERR)重定向到"nul",然后在删除命令后使用“if file exists ...”来查看是否有进一步的操作需要:

del somefile 2>&1 >nul
if exists somefile goto :someplace

问题是,STDERR 的重定向似乎失败​​了,因为我仍然收到错误消息:

c:\>del somefile 2>&1 >nul
Access is denied.

c:\>

无论我是从批处理文件还是从命令提示符执行此操作,都会发生这种情况。

我知道我可以使用 del/F(强制)开关来强制删除(并避免错误消息),如下所示:

c:\>del /F somefile 2>&1 >nul

c:\>

但是,我无法了解情况并在必要时采取其他行动(比如提示用户......)。此外,删除命令因其他原因(如文件正在使用中)而失败的(罕见)可能性,在这种情况下,我可能仍会看到 STDERR 的重定向失败。

解决方法是使用 attrib 命令(在 delete 命令之前)检查文件的 "read only" 状态,但这有点复杂,可能是最好使用“REGEX”和外部命令,如“grep”或“sed”(仍然非常可行)。

cmd.exe”的这种行为是否已知?是否有某些原因不将其视为 "bug"?

有什么方法可以强制“cmd.exe”重定向此 Access is denied. 消息吗?

您应该使用 >nul 2>&1 而不是 2>&1 >nul。当说 2>&1 时,您不会将其输出到默认输出,而是将错误输出重定向到默认输出的副本。但是,因为这是从左到右解释的,所以您首先将错误输出重定向到默认输出的副本,因此到屏幕,然后将 only 默认输出重定向到 nul。