Рассмотрим следующую метку с текстом, добавленным после нее, чтобы прояснить, для чего нужны аргументы в пакетном сценарии (все, что после пробела игнорируется...):
:LineBuilder [1 - main var type 1] [2 - main var type 2] [3 - subvar type] [4 - string to store in 1.3] [5 - Option for giving the length vs needing to calculate it] [6 - var containing Width to pull from] [7 - var containing Blanks to pull from] [8 - Option to add CRLF at the end of string] [9 - Border Option] [10 - Option to justify text 1/left, 2/right, 3/split - right text supplied Arg4, 4/centered, 5/split - left text supplied Arg5] [11 - Left portion of Text if Justy is split [spaces in between text]]
Что касается этой SO статьи, я знаю, что максимальная длина самого Label составляет 128 символов. Задокументировано ли также, какой длины может быть текст после метки? Если это официально не задокументировано или на этот конкретный вопрос еще нет ответа, возможно, у меня есть ответ, но я хочу подтвердить, что он не указан где-то еще.
Не считая двоеточия (:), вся строка состоит из 511 символов. Длина следующей строки, включая все пробелы (и пробел, отделяющий arg clarifications от самого Label), составляет 500 символов. В конечном итоге я наткнулся на эту ошибку, и мне потребовалось некоторое время, чтобы ее определить! Оказалось, что интерпретатор строки CMD отказался от попыток сохранить данные строки Label's в одной строке и попытался проанализировать окончательную ] как команду! (Если добавить REM сразу после первого места, ошибка изменится на ext]] — увеличение ровно на 4 символа.
']' is not recognized as an internal or external command, operable program or batch file.
Испытываю это в Windows 10.
Основываясь на ответе Джеба ниже и вопросе в комментариях, я могу подтвердить, что файл сохранен как CR LF окончания строк (проверено, как показано в NotePad++, кодировка UTF-8 (имеет ли это значение?). . .
Минимальный пример, показывающий, где он используется:
REM <<<-_-_-_-_-_END :OtherRoutine_-_-_-_-_->>>
REM Description Box
REM Other "SubRoutine Code"
Call :LineBuilder "consolText" "consol" "lineOne" "Searching for Corrupted Files. Please wait." "44" "consol.width" "consol.blanks" "1" "0" "1" ""
REM Other "SubRoutine Code"
Goto :EOF
REM <<<-_-_-_-_-_END :OtherRoutine_-_-_-_-_->>>
REM ╔══════════════════════════════════════════════════════╗
REM ║ -LineBuilder- ║
REM ║Sets the variable for specified line to equal the text║
REM ║supplied, takes the line variable, gets the string ║
REM ║length, and then calls ComputeLineLen to establish the║
REM ║total console's line length to set the blanks. Then it║
REM ║sets the line's blanks length and establishes the ║
REM ║fully computed line for output in MainPrompt, with ║
REM ║the spaces justified left, right, split, or centered. ║
REM ╚══════════════════════════════════════════════════════╝
REM <<<-_-_-_-_-_BEGIN :LineBuilder_-_-_-_-_->>>
:LineBuilder [1 - main var type 1] [2 - main var type 2] [3 - subvar type] [4 - string to store in 1.3] [5 - Option for giving the length vs needing to calculate it] [6 - var containing Width to pull from] [7 - var containing Blanks to pull from] [8 - Option to add CRLF at the end of string] [9 - Border Option] [10 - Option to justify text 1/left, 2/right, 3/split - right text supplied Arg4, 4/centered, 5/split - left text supplied Arg5] [11 - Left portion of Text if Justy is split [spaces in between text]]
<nul (set /p "lineOut= LineBuilder:!cr!!lf!")>>%log%
<nul (set /p "lineOut= LineBuilder:!cr!!lf!")>>%formLog%
REM More Code
Goto :EOF
REM <<<-_-_-_-_-_END :LineBuilder_-_-_-_-_->>>
Если я изменю текст после метки на следующий, ошибка исчезнет:
:LineBuilder [1 - main var type 1] [2 - main var type 2] [3 - subvar type] [4 - string to store in 1.3] [5 - Option for giving the length vs needing to calculate it] [6 - var containing Width to pull from] [7 - var containing Blanks to pull from] [8 - Option to add CRLF at end of string] [9 - Border Option] [10 - Option to justify text 1/left, 2/right, 3/split - right text supplied Arg4, 4/centered, 5/split - left text supplied Arg5] [11 - Left/right Text if Justy is split [spaces in text]]
Моя операционная система — Windows 10. Для ясности в вопрос добавлена эта информация вместе с тегом.
Да, меня тоже это интересовало - отсюда и моя ссылка на статью SO (где она была протестирована и показала 128... Незначительная разница меня не беспокоит). Просто очень любопытно, что это происходит. Не знаю, произошло ли это просто из-за структуры данных после метки или нет
Мир чудес... Кстати: я не могу реплицировать (Win11), даже если утрою вашу строку аргумента (метка заканчивается на первом пробеле, остальную часть строки следует игнорировать)
Почему этот вопрос был закрыт? Пожалуйста, укажите мне точное утверждение, где я нахожусь seeking recommendations for books, tools, software libraries, and more - я не понимаю, как любой вопрос может быть истолкован таким образом.
Ну, если вам просто не нужен логический ответ (который здесь не совсем по теме): «Это где-нибудь задокументировано?» очень похоже на заявление, направленное именно на это!
Однако что не имеет смысла, так это то, что в бесчисленных вопросах говорится о undocumented предметах из cmd.exe - поэтому ответ на этот вопрос был бы просто «Да» или «Нет» - если бы я спросил: «Какой лучший документированный ответ на этот вопрос?» этот вопрос?" тогда я мог бы рассматривать это как поиск рекомендации. Я ищу ответ, основанный на фактах - если он не задокументирован, где же искать ответ, если не здесь? Спросить: «Это где-нибудь задокументировано?» спрашивает именно об этом - о правдивом ответе, чтобы не тратить больше времени на ожидание ответа здесь, когда я смогу прочитать документацию.
Я только что посмотрел на вопрос еще раз - я удалю вопрос в конце, поскольку это ДОЛЖЕН быть единственный вопрос, который может быть неправильно истолкован. . .
@Стефан, твоя строка в конце метки также содержит скобки?
да, попробовал с указанной вами командой, и когда она не выдала ошибок, я просто удвоил и, наконец, утроил строку «аргументы» (все еще заканчивающуюся на ]]) - ошибок по-прежнему нет. (Тем временем у меня была возможность попробовать это и на Win10 - такое же поведение: ошибок нет)
Хмммм. Изменится ли изменение кодовой страницы? Я запускаю chcp 65001 в начале командного файла, потому что использую символы extended DOS Ascii для индикатора выполнения. Кроме того, enabledelayedexpansion и enableextensions также установлены глобально для всего файла.
setlocal enabledelayedexpansion и chcp 65001 для меня не имеют значения. Все еще работает нормально на Win10 и Win11.
Описание ошибки напоминает мне о проблеме с символом окончания строки в Linux. Это происходит на границах 256 или 512 байт, когда используется LF вместо CR/LF. Кстати. Строка не должна быть длиннее ~ 8191+cmd tokensize. Это возможно, но тогда возникают более неясные проблемы.
Добавьте полный пример минимального пакетного файла, в котором возникает проблема.
Понятия не имею, почему, но теперь я могу воспроизвести проблему (тот же код, что и раньше). Ваша первая метка не показывала ошибку (строка состояла ровно из 512 символов), но в добавленном вами коде перед вами есть пробел. двоеточия, что составляет 513 символов в строке, что указывает на заявленную вами ошибку. Это объясняет, почему моя первая попытка прошла успешно, но не объясняет, почему она сработала нормально с добавлением дополнительных символов. Я не нашел ни одного источника, в котором упоминалось бы ограничение в 512 байт.





Минимальный пример длинных строк меток:
@echo off
goto :myLabel
:myLabel xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx12345678
Вывод «345678» не распознается как внутренняя или внешняя команда, исполняемая программа или командный файл.
В строке метки текст «1234578» начинается после 512 начальных символов (имя метки через двоеточие и множество x).
Вероятно, парсер меток имеет буфер на 512 байт (+2 для CRLF), когда в этом буфере не найден CRLF, он просто прекращает поиск CRLF и просто использует следующие символы.
Правило такое: если строка метки длиннее 514 байт, анализатор просто принимает следующую команду в позиции 514.
Кстати, вам следует решить свою проблему, просто переместив описание на следующую строку. это гораздо читабельнее, чем одна сверхдлинная строка.
:LineBuilder
::: [1 - main var type 1]
::: [2 - main var type 2]
::: [3 - subvar type]
::: [4 - string to store in 1.3]
::: [5 - Option for giving the length vs needing to calculate it]
::: [6 - var containing Width to pull from]
::: [7 - var containing Blanks to pull from]
::: [8 - Option to add CRLF at the end of string]
::: [9 - Border Option]
::: [10 - Option to justify text 1/left, 2/right, 3/split - right text supplied Arg4, 4/centered, 5/split - left text supplied Arg5]
::: [11 - Left portion of Text if Justy is split [spaces in between text]]
Из соображений скорости лучше поместить описание перед меткой.
Еще один пример проблемы такого рода, но он связан с окончаниями строк.
@echo off
goto :LineBuilder
REM 12345678
:LineBuilder [1 - main var type 1] [2 - main var type 2] [3 - subvar type] [4 - string to store in 1.3] [5 - Option for giving the length vs needing to calculate it] [6 - var containing Width to pull from] [7 - var containing Blanks to pull from] [8 - Option to add CRLF at the end of string] [9 - Border Option] [10 - Option to justify text 1/left, 2/right, 3/split - right text supplied Arg4, 4/centered, 5/split - left text supplied Arg5] [11 - Left portion of Text if Justy is split [spaces in between text]]
Сохраните это с окончаниями строк LF (с помощью vscode вы можете переключаться между CRLF и LF)
Тогда вы получите:
«между» не распознается как внутренняя или внешняя команда, исполняемая программа или командный файл.
Команда «неизвестно» зависит только от количества символов в строке REM.
Как решить?
Сохраните файл с окончаниями строк CRLF или используйте
more defectBatch.bat > workingBatch.bat
Я использую NotePad++, окончания строк — CRLF. Я добавлю это к содержанию вопроса, но это полезно знать на случай, если когда-нибудь появится определенная ниша, в которой кто-то столкнется с этим!
Также с помощью поиска по RegEx только что подтверждено, что рассматриваемые строки также заканчиваются на \r\n на случай, если предыдущая находка/замена RegEx в NPP вызвала проблему.
Чтобы быть предельно внимательным к тому, что вы предложили, я также использовал команду для вывода содержимого файла в «исправленную» версию командного файла, затем запустил FileCompare через CMD и не обнаружил никаких различий между оригиналом и «исправленной» версией. файла.
@ k1dfr0std Вы правы, мое предложение решает проблемы только тогда, когда используются неправильные окончания строк. для вашей проблемы решение - уменьшить длину строки
Замечательно добавьте обновление к вашему ответу! Раньше я помещал «Параметры» в строки над меткой, но, работая с более надежными языками, такими как VB.Net, я старался сохранить свой код как можно более структурированным, поэтому возвращался к той же строке, что и наклейка. Рады обнаружить новое ограничение в CMD! Следующий вопрос может потребовать отдельного вопроса, но с появлением знания о том, что максимальное количество символов составляет 512 символов: будет ли код выполняться быстрее, если я помещу параметры в строки, предшествующие метке, или оставлю их сразу после метки?
@k1dfr0std Кстати. Я нашла пост за 2019 год , в котором уже описывалось поведение (И это я сам). В протекторе также описаны другие странные эффекты.
Это было великолепное чтение! Другой пост также ответил на еще один давний вопрос: «Имеет ли значение, указаны ли параметры до или после метки?» а именно - «Нет». - эффект все равно будет тот же. Отличная сделка.
Я не могу воспроизвести вашу проблему в Windows 11. Какую версию Windows вы используете?