Почему rem влияет на блок кода, вывод которого передается по конвейеру?

Мне нравится использовать блоки команд, заключенные в круглые скобки, так как это позволяет мне передавать вывод всех команд в блоке в more (или любую другую команду) одновременно.

Обычно я могу добавлять примечания (rem) и внутри этих блоков.

Однако я не могу совместить эти две функции: блок с примечаниями, переданными в more (или любую другую команду), вообще не выполняется. Почему это? Можно ли это решить?

@echo off
rem This works (prints X1)
(
    echo X1
)

rem This works (prints X2)
(
    echo X2
) | more

rem This works (prints X3)
(
    rem
    echo X3
)

rem Why does this print nothing?
(
    rem
    echo X4
) | more

rem Or this?
(
    echo X4
    rem
) | more

rem This works (prints X5)
(
    :: Using colons instead of rem
    echo X5
) | more

Очаровательный. Если редиректор >, он работает как положено. Мне кажется, это проблема @jeb...

Magoo 08.02.2023 07:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
1
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это из-за складывания.
Использование каналов приводит к созданию двух отдельных дочерних процессов cmd.exe. Но код должен быть свернут, прежде чем он будет передан в cmd.exe, особенно блоки кода.

Правило складывания простое, каждая новая строка будет переведена в амперсанд.
Так выглядит сложенный блок

( echo X1 & echo X2 )

Но с REM вы получаете

( REM & echo X4 ) 

REM помечает остальную часть строки, амперсанд больше не действует, и закрывающая скобка также помечается.

Если REM после этого ECHO, это та же проблема.

( echo X4 & REM ) 

Последняя часть отмечена, поэтому есть только ( echo X4 и отсутствует закрывающая скобка.

Но почему :: комментарии работают?
Похоже, :: должна привести к той же ошибке, что и REM, но это работает!
Это потому, что метки :: полностью удалены из блока кода, поэтому результирующая строка для блока, подобного

( 
  :: My comment
  echo X4
)

Результаты просто:

C:\Windows\system32\cmd.exe  /S /D /c" ( echo X4 )"

Как заставить REM работать в конвейерных блоках?

Самый простой способ — использовать REM., но это не совсем настоящий REM, он не может закомментировать амперсанд или другие специальные символы.

( 
  REM. This is a comment, special characters aren't allowed here
  echo This works
) | more

Или используйте дополнительный перевод строки в строке REM

(set \n=^
%=THIS LINE IS REQUIRED=%
)
( 
  REM This is a comment with & and | %%\n%% BREAK
  echo This works
) | more

Как отлаживать свернутые блоки?

Это просто с псевдопеременной cmdcmdline

(
  echo Debug %%cmdcmdline%%%
  echo one
  echo two
) | findstr /n "^"

Результат:

1:Отладка C:\Windows\system32\cmd.exe /S /D /c" ( эхо отладки %cmdcmdline% & echo one & echo two )"
2: один
3: два

См. также Почему отложенное расширение не работает, когда оно находится внутри конвейерного блока кода?

Это объяснение звучит разумно, но оно не объясняет, почему блок кода не выполняется с echo X4, за которым следует (не предшествует) rem, не так ли? Потому что echo X4 & rem в одной строке отлично работает за пределами блока. Или в этом случае отмечены закрывающие скобки?

bers 08.02.2023 07:11

@bers я добавил дополнительное объяснение для этого случая

jeb 08.02.2023 07:14

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