Перенаправление файлов в Windows и%errorlevel%

Допустим, мы хотим создать пустой файл в Windows с помощью следующей команды:

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

каталог не существует, поэтому мы получаем ошибку:

The system cannot find the path specified

Если вы распечатаете %errorlevel% выход:

echo %errorlevel%
0

Тем не менее команда не была успешной!

Я заметил, что Windows не устанавливает %errorlevel% последней команды, если вы используете перенаправление..

Это можно обойти?

1 ответ

Решение

Вы можете использовать следующее:

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

Команда

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

вызывается с несуществующим путем, завершается при сбое перенаправления и typeвообще не вызывается. Следовательно, у него нет возможности установитьERRORLEVEL. Перенаправление, выполняемое оболочкой, не устанавливает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, который мог быть установлен правильно или неправильно.

Герберт Kleebauer объяснил это мне в Usenet группеalt.msdos.batch.

Обновление:
анонимный пользователь предложил альтернативное решение на основеCOPY команда:

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

Эта команда устанавливает ERRORLEVEL, который может быть проанализирован следующей командой в скрипте. Очень удобно, поэтому я благодарю его за предложенную правку.

Другие вопросы по тегам