Windows中的文件重定向和%errorlevel%

25

假设我们想要使用以下命令在Windows中创建一个空文件:

type nul > C:\does\not\exist\file.txt

目录不存在,所以我们会收到这个错误:

The system cannot find the path specified

如果你打印出%errorlevel%,输出结果将会是:

echo %errorlevel%
0

然而,命令并没有成功执行!

我注意到,如果使用重定向,Windows不会设置最后一个命令的%errorlevel%

有什么解决办法吗?

2个回答

32
您可以使用以下内容:

您可以使用以下方法:

C:\>type nul > C:\does\not\exist\file.txt && echo ok || echo fail
The system cannot find the path specified.
fail

C:\>echo %errorlevel%
1

我一直以为 && 和 || 运算符使用 ERRORLEVEL,但显然不是这样。

非常奇怪的是,只有当你使用 || 运算符时,ERRORLEVEL 才会在重定向错误之后被设置。我从未想到过。如果不是因为你出色的问题,我也永远不会去测试。

如果你想要做的仅仅是在重定向失败时设置 ERRORLEVEL,那么你当然可以简单地执行如下操作:

type nul > C:\does\not\exist\file.txt || rem

1
@AndriyM - 你确定在测试开始前 ERRORLEVEL 是0吗?无论在 XP 还是 Vista 中,' && REM ' 对我都不能“修复” ERRORLEVEL。 - dbenham
1
@jeb - 我不理解你的理论。但我同意这是非常出乎意料的行为。我有很多处理重定向错误的代码,但我总是使用 || 运算符,因为我喜欢它的紧凑性。所以在这个问题出现之前,我从未发现过这种奇怪的行为。 - dbenham
我不明白 type nul > C:\does\not\exist\file.txt || rem 的作用是什么。在我的机器上(Win Server 2012 R2),它没有改变 ERRORLEVEL - 它的值与重定向之前的最后一条命令设置的值相同。 - Ohad Schneider
@OhadSchneider - 我不能代表Win Server 2012发言,但在XP、Vista、Win7和Win10上,type nul >"bogusPath\test.txt" || rem将在路径“bogusPath\”不存在时将ERRORLEVEL设置为1。 - dbenham
好的,我想我明白发生了什么。我使用的是 echo 而不是 type,例如 echo nul >"realpath.txt" || rem,由于 echo 不会改变 ERRORLEVEL,所以我没有看到变化。 - Ohad Schneider
显示剩余5条评论

1

这个命令

type nul > C:\does\not\exist\file.txt

当使用不存在的路径调用时,将在重定向失败时终止,并且不会调用type。因此,它没有机会设置ERRORLEVEL。由shell执行的重定向不会设置ERRORLEVEL

一种解决方案是使用非零值预先初始化ERRORLEVEL。 它在失败时保持不变,并在成功时被type重置为零:

@echo off
::pre-initialise ERRORLEVEL with a value of 1:
call :SETERROR 1
type NUL > NOSUCHDIR\test.txt
IF ERRORLEVEL 1 goto ERROR
echo All is well.
goto END
:ERROR
echo Error detected.
:END
goto :eof
:SETERROR
exit /b %1

这是一个短表单

type NUL > NOSUCHDIR\test.txt && goto OK || goto ERROR

这是因为它分析了退出代码,而退出代码与错误级别不同:

退出代码可以直接通过重定向运算符(忽略ERRORLEVEL的成功/失败)进行检测,这通常比信任ERRORLEVEL更可靠,因为ERRORLEVEL可能已正确或错误地设置。

Herbert Kleebauer在Usenet组alt.msdos.batch中向我解释了这一点。

更新:
一位匿名用户基于COPY命令提出了另一种解决方案:

COPY NUL: C:\does\not\exist\file.txt

这个命令会设置ERRORLEVEL,下一个脚本中的命令可能会对其进行分析。非常方便,因此我感谢他提出的修改建议。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接