Почему ErrorLevel устанавливается только после || оператор при неудачном перенаправлении?

При неудачном перенаправлении (из-за несуществующего файла или недостаточного доступа к файлу),ErrorLevel значение не установлено (в следующих примерах файлtest.tmp защищен от записи и файловtest.nil не существует):

>>> (call ) & rem // (reset `ErrorLevel`)

>>> > "test.tmp" echo Text
Access is denied.

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=0

>>> (call ) & rem // (reset `ErrorLevel`)

>>> < "test.nil" set /P DUMMY=""
The system cannot find the file specified.

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=0

Однако, как только за ошибочным перенаправлением следует оператор условной конкатенации||, который запрашивает код выхода,ErrorLevel становится установленным1неожиданно

>>> (call ) & rem // (reset `ErrorLevel`)

>>> (> "test.tmp" echo Text) || echo Fail
Access is denied.
Fail

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=1

>>> (call ) & rem // (reset `ErrorLevel`)

>>> (< "test.nil" set /P DUMMY="") || echo Fail
The system cannot find the file specified.

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=1

Что интересно,ErrorLevel остатки0 когда оператор&& используется:

>>> (call ) & rem // (reset `ErrorLevel`)

>>> (> "test.tmp" echo Text) && echo Pass
Access is denied.

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=0

>>> (call ) & rem // (reset `ErrorLevel`)

>>> (< "test.nil" set /P DUMMY="") && echo Pass
The system cannot find the file specified.

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=0

ErrorLevel остается также0 используя оператора&:

>>> (call ) & rem // (reset `ErrorLevel`)

>>> (> "test.tmp" echo Text) & echo Pass or Fail
Access is denied.
Pass or Fail

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=0

>>> (call ) & rem // (reset `ErrorLevel`)

>>> (< "test.nil" set /P DUMMY="") & echo Pass or Fail
The system cannot find the file specified.
Pass or Fail

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=0

В случае, если оба оператора условной конкатенации&& а также|| появляются,ErrorLevel установлен в1 тоже (если|| происходит раньше&&обе ветви выполняются как в предыдущем примере, но я думаю, что это только потому, что&& оценивает код выхода предыдущегоecho команды):

>>> (call ) & rem // (reset `ErrorLevel`)

>>> (> "test.tmp" echo Text) && echo Pass || echo Fail
Access is denied.
Fail

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=1

>>> (call ) & rem // (reset `ErrorLevel`)

>>> (< "test.nil" set /P DUMMY="") || echo Fail && echo Pass
The system cannot find the file specified.
Fail
Pass

>>> echo ErrorLevel=%ErrorLevel%
ErrorLevel=1

Так какова связь междуErrorLevel значение и|| оператор, почемуErrorLevel зависит от||? Является|| копирование кода выхода вErrorLevel? Возможно ли все это только с (неудачными) перенаправлениями, потому что они обрабатываются до выполнения каких-либо команд?

Еще более странно, я не мог наблюдать противоположное поведение -ErrorLevel сбрасывается на0 от&& - при правильном возврате тестовой настройки (то есть замена(call ) от(call) (установитьErrorLevel в1 изначально), очистив атрибут «только чтение» файлаtest.tmp, создание файлаtest.nil (первая строка не пустая, чтобы избежатьset /P установитьErrorLevel в1) и используя расширение файла.bat скорее, чем.cmd для тестирования (чтобы избежатьset /P сброситьErrorLevel в0)).

Я наблюдал описанное поведение в Windows 7 и Windows 10.

Ответы на вопрос(2)

Ваш ответ на вопрос