Объединение многострочной пакетной команды со встроенными комментариями

У меня очень длинная строка командной строки, и я хочу прокомментировать некоторые аргументы/переключатели и описать, что они делают и что с их помощью можно настроить. следующий упрощенный пакетный файл не работает, но это более или менее то, что я хочу сделать:

executable^
 -switch1=3^                   rem should be 3 or 5, three means xxx and 5 means yyy
 -argument1=some-file.txt^
 -file-format=csv^             rem output file format, supported are csv and xml
 -out=result                   rem written file, file extension is copied from file format

Я создал простой скрипт для проверки синтаксиса объединения комментариев с командной строкой разделения, но не смог найти рабочего решения:

rem WORKS, no space after caret
echo aaa ^
bbb

rem does not work, space after caret
echo aaa ^ 
bbb

rem WORKS space in the next line
echo aaa ^
 bbb
echo(
echo and now with rem-comments
echo(

rem does not work
echo aaa ^rem comment
bbb

rem does not work
echo aaa ^&rem comment
bbb

rem does not work
echo aaa ^ rem comment
bbb

rem does not work
echo aaa ^ &rem comment
bbb
echo(
echo and with double-colon-comments
echo(

:: does not work
echo aaa ^:: comment
bbb

:: does not work
echo aaa ^&:: comment
bbb

:: does not work
echo aaa ^ :: comment
bbb

:: does not work
echo aaa ^ &:: comment
bbb

Кажется, что любой символ после курсора нарушает его, поэтому может быть вообще невозможно иметь встроенный комментарий после курсора? Есть ли у кого-нибудь идея/решение?

Нет, каретка — это escape-символ, который, по сути, экранирует следующий перевод строки (очень сжатое описание). Все, что после него, разрушает этот эффект. То, что пробел (и/или некоторые другие символы) работает, связано с тем, как парсер распознает и «переводит» строку.

Stephan 03.09.2024 08:30

Подсказка не по теме: Прочтите тему на форуме DosTips: ЭХО. НЕВОЗМОЖНО ввести текст или пустую строку. Вместо этого используйте ECHO/ Использование echo. всегда приводит к доступу к файловой системе для поиска файла с именем echo в текущем каталоге. Точка в конце автоматически удаляется функциями файлового ввода-вывода Windows. Лучше использовать echo/ или echo( для вывода пустой строки, что в данном случае делается без доступа к файловой системе, что делает командный файл более отказоустойчивым и обрабатывается немного быстрее.

Mofi 03.09.2024 12:34

Это полезно знать, спасибо за подсказку!

Michael 03.09.2024 13:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
3
52
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Невозможно иметь такие команды, как rem, внутри команды, распределенной по нескольким строкам. Символ каретки ^ в качестве escape-символа в конце строки работает только при наличии следующего возврата каретки (игнорируется при автоматическом чтении пакетного файла) и перевода строки. Даже конечный пробел, такой как обычный пробел или горизонтальная табуляция, приведет к разделению длинной командной строки на две командные строки, и выполнение исполняемого файла не будет работать должным образом. Командный процессор Windows использует очень старый синтаксис, который не поддерживает пробелы и табуляцию, как современные интерпретаторы сценариев. Дополнительную информацию об обработке командной строки или пакетного файла см. в разделе Как интерпретатор команд Windows (CMD.EXE) анализирует сценарии?

Решение очень простое. Длинная командная строка записывается в пакетном файле как одна длинная командная строка, и все параметры объясняются в блоке выше, который более или менее игнорируется при выполнении с использованием команды goto, как показано ниже.

goto RunExe
rem   -switch1=3 ......... should be 3 or 5, three means xxx and 5 means yyy
rem   -file-format=csv ... output file format, supported are csv and xml
rem   -out=result ........ written file, file extension is copied from file format
:RunExe
executable -switch1=3 -argument1=some-file.txt -file-format=csv

отличная читабельность (👍👍👍), близкая к типичным справочным/справочным страницам. я вижу только один очень маленький недостаток: у вас есть все переключатели и аргументы дважды, вам нужно синхронизировать комментарий при настройке/настройке реальной командной строки... но, конечно, это человеческая проблема 😁

Michael 03.09.2024 10:24
Ответ принят как подходящий

Вы можете использовать процентные комментарии.
Они полностью исчезают с линии, поэтому не мешают.

echo aaa ^%=     My first comment here =%
bbb^%=           Second comment        =%
ccc%=            My last comment       =%

Это работает, потому что парсер пытается расширить комментарий как переменную, но если он не может найти такую ​​переменную, он расширяется до пустой строки.
Поэтому начинать следует с %=, потому что переменные не могут быть созданы с начальным знаком равенства.
Важно не включать в комментарии двоеточия, поскольку они рассматриваются как специальные операторы модификации переменных и полностью нарушают комментарий.

Процентный комментарий можно использовать практически в любой позиции строки.

echo aaa ^%= My comment here =%
bbb%= This comment is in front of the caret=%^
c%=This comment is inside the text =%cc

Это очень интересное решение 👍 Все еще не уверен, собираюсь ли я (или должен) использовать его по двум причинам: а) подсветка синтаксиса в npp игнорирует его (потому что это не комментарий, а намеренно неправильное объявление переменной) б) если кто-то другой в моей компании не знают, что двоеточия в этой записи запрещены, это может вызвать проблемы. И, конечно, я не знаю, помню ли я, что двоеточия запрещены, когда мне придется изменить командный файл в будущем 😂

Michael 03.09.2024 10:11

@Майкл Ты прав. Но я вообще советую не использовать пакетные файлы в продакшене (хотя по тегу пакетных файлов я занимаю второе место среди лучших пользователей). Усилия по написанию стабильных и безошибочных пакетных файлов просто слишком велики.

jeb 03.09.2024 10:57

Я бы не назвал это производством напрямую (не доставкой клиентам), мы используем пакетные файлы для внутренних вещей, таких как средства запуска для клиент-серверных Java-приложений, openssl и ffmpeg. эти пакетные файлы уже существуют, но неинтересно копаться в openssl или ffmpeg, если вы какое-то время не трогали эти файлы. вот почему я ищу что-то, чтобы документировать переключатели/аргументы в пакетном файле как можно ближе к фактическому аргументу...

Michael 03.09.2024 12:53

Я отмечу ваш ответ как принятый, поскольку он соответствует тому, о чем я просил, но я воспользуюсь предложением Мофи для документации, так как считаю, что его легче читать.

Michael 03.09.2024 12:55

Ваша первоначальная концепция неверна, потому что символ конца строки ^ должен быть помещен в конец строки...

Я предлагаю другой подход, в котором нет проблем с двоеточиями в комментариях:

@echo off 
setlocal EnableDelayedExpansion

set ^"\n=^
%don't remove%
^"

set "command = "
for /F "delims=/" %%a in (^"

executable                                                                          !\n!
 -switch1^=3               // should be: 3 or 5, three means xxx and 5 means yyy    !\n!
 -argument1^=some-file.txt                                                          !\n!
 -file-format^=csv         // output file format, supported are: csv and xml        !\n!
 -out^=result              // written file, file extension is copied from file format

^") do set "command=!command! %%a"

%command%

В этом методе сначала создается переменная «конец строки» \n и помещается в конец каждой строки, содержащей команду. Каждая строка обрабатывается командой for /F и используется для сборки окончательной команды. «Часть комментария» отделяется косой чертой, которая включена в часть delims=/ команды FOR /F. Вы также можете использовать заглавную букву «R» в качестве разделителя комментариев и разделять комментарии с помощью команды REM.

Выполненная команда такова:

executable   -switch1=3   -argument1=some-file.txt   -file-format=csv   -out=result

Единственным недостатком этого метода является то, что знаки равенства необходимо ^= экранировать, поскольку синтаксический анализатор их удаляет.

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