![]() ![]() ![]() |
|
Наиболее частые ошибки, заметки особенностей программинга BAT файлов, баги интерпретатора*10.01.2013, 15:41. Показов 125691. Ответов 116
Метки %~dp0, chcp 1251, кодировка в консоли, оптимизация кода, режим вывода команд на экран (echo) включен, текущий рабочий каталог bat, украинский cmd/bat, экранирование спецсимвола (Все метки)
Эта тема - ответвление Тонкости языка, редкие команды и сложные скрипты
Постим сюда детали, которые Вы получили опытным путем. Которые считаете уникальными, или могут быть полезными при наборе кода BAT файлов, лучшего понимания принципов работы среды командной строки. Пишем ошибки, которые иногда допускаете, а потом ломаете голову, почему не работает ![]() Писать можно много и часто, даже если это мелочь. Все соберем вместе. Весомые замечания перенесем в указанную выше тему. Собрано по категориям: Файловые операции 5) Использование рабочего каталога Bat файла в роле начального для выполнения команд в нем на ОС >= Vista ссылка 8) Как проверить - существует ли папка ссылка 10) Не использовать && после команды Del. ссылка 12) После перехода в другой каталог проверять успех операции ссылка 18) Листинг текущего каталога или корневого ссылка 24) Работа с файлами/папками, в именах которых есть буквы украинского алфавита. ссылка Символы 1) Экранирование спецсимвола ссылка 13) Сохранение концевого пробела в переменную ссылка 17) Запятая и точка с запятой - разделители аргументов ссылка 30) Экранирование номера потока в перенаправлении вывода Echo ссылка Переменные 2) Использование одноименных переменных без обнуления ссылка 3) Пренебрежение Setlocal ссылка 3.1) Не указав Setlocal EnableDelayedExpansion, используем знаки восклицания (!) для раскрытия значения переменных ссылка 6) Инициализация числового типа данных ссылка 14) Обход ошибки "Режим вывода команд на экран (ECHO) включен" ссылка 16) Пробелы тоже могут являться частью названия переменной ссылка 23) Для команды SET всегда заключайте в кавычки переменную и значение, если ним является изменяемое имя файла ссылка 28) Двойное раскрытие переменной. Первыми раскрываются проценты. ссылка 29) Конструкция вида Echo.!Var:~0,1! не работает. ссылка Циклы 7) EOL в цикле FOR - правильный порядок модификаторов ссылка 9) Использовать UseBackQ при чтении содержимого файла, имя которого может меняться ссылка 25) Получение даты и времени файла через цикл и команду For без ключа /S (рекурсия) и подпрограммы ссылка Кодировка 4) Сохранение BAT-файла с кодировкой перевода строк в UNIX-стандарте ссылка 26) Кодировка в консоли ссылка 27) Текстовой файл не читается циклом по неизвестной причине ссылка Тесты, оптимизация и граничные возможности интерпретатора 15) Граничные значения для числового типа в CMD ссылка 19) Максимальная глубина рекурсии = 593*. ссылка 20) Максимальная длина значения строки ссылка 21) Оптимизация кода ссылка 22) Тест замедления работы операторов при перегрузке оперативной памяти ссылка Другое 1) Указывая метку подпрограммы, можно через пробел указывать ее описание. Среда не будет "ругаться" ссылка 11) Внимательно выбирайте имя для BAT(CMD)-файла ссылка
0
|
10.01.2013, 15:41 | |
Ответы с готовыми решениями:
116
Ошибки при запуске bat-файлов
Как определить количество цветов в подгружаемом рисунке и наиболее частые цвета |
2 / 2 / 0
Регистрация: 05.09.2017
Сообщений: 4
|
|||||||||||||||||
20.09.2017, 21:56 | |||||||||||||||||
Тем не менее наступал на эти грабли несколько раз за последние 10-ть лет ![]() Добавлено через 2 часа 47 минут Еще вспомнил одну особенность команды RD. С тех пор, как перешел на Windows7 (лет пять тому) обнаружил, что RmDir не возвращает код ошибки. (На Windows XP не помню, чтобы сталкивался с этим). Мне сложно понять почему это происходит и как это объяснить с "научной" точки зрения, но покажу на практическом примере. Кстати такое поведение наблюдалось не только в RmDir, но не помню точно с какими командами еще. В данном случае с заведомо неверным параметром, код ошибки будет все-ровно 0.
Но я неуверен, как это правильно можно объяснить.
1
|
1 / 1 / 0
Регистрация: 15.04.2017
Сообщений: 25
|
||||||
30.11.2017, 13:47 | ||||||
Кусок кода с поиском числа строк и последней строки (с последующем обрезанием ненужного):
P.S. Данные с датчика, где первая строка - время в мсек с момента запуска системы. Как обойти проблему, кроме подключения дополнительного фильтра по размеру файла с учетом минимально возможной (или средней) длины строки - не знаю.
0
|
![]() ![]() ![]() |
|
01.12.2017, 00:13 [ТС] | |
parmari, просто не понятно, зачем вы сюда это выложили и как относится к багам интерпретатора.
Под аналитической информацией подразумевается развёрнутый ответ, что вот так и при таком количестве будет виснуть -> следовательно нужно делать вот так и так, или вообще не использовать CMD. Вы констатируете проблему и хотите получить помощь в её решении? Тогда создайте новую тему, и там вам предложат более быстрые варианты. А магическое число здесь никак не является решающим фактором. Ваш код трудно назвать оптимизированным.
0
|
1 / 1 / 0
Регистрация: 15.04.2017
Сообщений: 25
|
|
01.12.2017, 13:44 | |
Ладно, в сухом остатке...
На файлах, размер строк которых >65535, при построчной обработке циклом, батник виснет так, словно уходит в бесконечный цикл. Ждать окончания работы - бессмысленно (за ночь ничего не произошло), в то время как файлы меньшего размера (хотя бы на 1 строку!) обрабатывались тем же способом в пределах несколько минут. Видимо, эта проблема связана с особенностью использования оперативной памяти bat -файлом, поэтому так делать не надо. Относится ли этот факт к данной теме или нет - на усмотрение модератора - но для меня он был бы в свое время полезен сам по себе.
0
|
![]() ![]() ![]() |
|
01.12.2017, 15:24 [ТС] | |
В том и дело, что батник не оптимизирован. При таком кол-ве строк, итерации создавать не имеет смысла.
Всё делается проще. find /c /v "" узнаётся кол-во строк. Find /n - добавление номера строки и передача в findstr для получения нужной строки. Затем всего 1 итерация, чтобы отбросить лишнюю часть с номером строки. В теме с полезными примерами решенных задач подобное есть по ссылкам.
1
|
![]() ![]() ![]() |
||||||||||||
26.11.2018, 19:17 [ТС] | ||||||||||||
more.exe и ошибки "Слишком много аргументов в командной строке"
В Windows 10 сломали совместимость со старым синтаксисом more.exe
2
|
5 / 5 / 0
Регистрация: 24.11.2014
Сообщений: 48
|
|
25.01.2020, 18:37 | |
Dragokas, большое спасибо за пример с UseBackQ (были проблемы с пробелами в пути и имени файла). Я почему-то был уверен, что это касается только содержимого читаемого файла.
0
|
![]() ![]() ![]() |
|||||||||||||||||||||
18.10.2020, 00:01 [ТС] | |||||||||||||||||||||
Баг с %~dp0 и планировщиком заданий
Если запустить батник C:\Users\user\desktop\1.bat из-под планировщика,
через call file тоже, т.к. CD = C:\Windows\System32 Попытаться обойти этот баг можно с помощью:
0
|
3 / 3 / 0
Регистрация: 24.03.2021
Сообщений: 1
|
|||||||||||
24.03.2021, 20:51 | |||||||||||
Я даже зарегистрировался, чтобы написать об этом, т.к. не нашёл
![]() Цикл for /r имеет один неприятный баг (или фичу), который может обломать с конечным результатом, т.к. ошибка при этом не выводится. Если в качестве начальной папки после for /r указать раскрываемую переменную из родительского цикла, то она просто не раскроется.
Если включено отложенное раскрытие переменных (SetLocal EnableDelayedExpansion), то парсер консоли неправильно обрабатывает имена файлов и папок, если в них есть восклицательный знак - он его просто убирает. Заключение в кавычки или экранирование через ^ не помогает. Будьте с этим осторожны. Родственная этой особенность: Если в подфункцию через call :Функция "аргумент" передаётся строка, в которой есть символ процента, то этот процент убирается. Здесь спасает удваивание знака (%%), вот только если мы работаем в аргументе с переменной, то удвоить просто так не получится. Команда call set "Var=%%Var:%=%%%%" не сработает, поэтому SetLocal EnableDelayedExpansion, похоже, здесь не избежишь. Добавлено через 14 минут Могу также написать про баги CMD при работе в Wine, которые годами никто не исправляет и которые могут даже натворить проблем с вашими данными. 1) Команда TYPE не может читать UTF8/UTF16-файлы, хотя Windows читает ещё начиная с Win 2000. 2) Команда DEL не поддерживает ключ /A без указания атрибутов. В Windows это означает удаление файлов с любыми атрибутами. 3) Команда MOVE не поддерживает ключ /Y для перезаписи файлов. Также она не поддерживает перемещение файлов между разделами дисков. 4) При чтении внешнего файла через FOR /F %%A "eol=# ..." ... будут читаться пустые строки файла, хотя в Windows они пропускаются. При отсутствии "eol=" пустые строки пропускаются. Это может вызывать некоторые проблемы. 5) Ошибка в синтаксисе при FOR ... DO IF ... ( перенос строки ). При FOR ... DO (IF ... ( перенос строки ) ) ошибки нет. 6) Если в теле условия IF "условие" (...) есть оператор FOR ... DO, и условие верно, то оператор ELSE в конце условия выдаст ошибку и не выполнится. 7) Если маску поиска файлов в операторе FOR заключить в кавычки, то маска не работает (например: FOR %%M IN ("Dir\*.exe") DO ...). 8) Если в теле IF/FOR (...) есть пустые строки с пробелами или табами, то выдаётся синтаксическая ошибка. 9) Если в FOR /F задать имя файла или строку без кавычек, то выдаётся синтаксическая ошибка. 9) Текст в строке команды PAUSE не переносит курсор на новую строку. Из-за этого следующий текст печатается в этой же строке (после паузы добавлять ECHO.) 10) Вынесение перенаправления "> xxx" за скобки ()-блока не работает и выдаёт ошибку. 11) Команда TASKLIST не работает (выдаёт пустой результат). 12) Команда TASKKILL не имеет ключа /T (завершения дерева процессов) и выдаёт ошибку, если он прописан в файле. 13) Командная строка и скрипты не работают, если они запускаются из софта, скрывающего окно консоли (типа hidcon.exe или InnoSetup). В версии 5.0 stable и более ранних - работало.
3
|
50 / 35 / 9
Регистрация: 13.06.2019
Сообщений: 208
|
||||||||||||||||
03.06.2021, 11:28 | ||||||||||||||||
тупейший но сложноуловимый глюк с перенаправлением
вот довольно дистиллированный (хотя и дающий представление о задаче) скрипт, воспроизводящий ошибку: processf.bat
выводит в конце какую-то лишнюю не понятную строку, частично дублирующую предидущий вывод на экран потратил почти два дня на отладку пока понял что глюк не связан ни с вызовами подпрограмм, ни с использованием всяких штук
а с перенаправлением, с перенаправлением Карл!.. так что желающие могут проверить себя: найти глюк, а потом посмотреть ответ ответ
0
|
![]() ![]() ![]() |
||||||
03.06.2021, 12:09 [ТС] | ||||||
mark74, поэтому всегда в случаях перенаправления вывода в файл оптимальней писать в обратном порядке, чтобы не зависеть от содержимого буфера:
2
|
5 / 5 / 0
Регистрация: 24.11.2014
Сообщений: 48
|
|
15.07.2021, 22:41 | |
Если в комментарии записать такую последовательность символов ( %~j ), то при выполнении CMD-файла мы получим сообщение:
«Следующее использование оператора пути при подстановке параметров в пакетных файлах является недопустимым: %~j Для просмотра списка допустимых форматов введите CALL /? или FOR /? Ошибка в синтаксисе команды.». И не важно чем мы комментируем ( Rem ) или ( :: ). Наверное, это нормальное поведение, но для меня это было открытием. Еле понял, что происходит.
0
|
1 / 1 / 0
Регистрация: 12.06.2015
Сообщений: 67
|
||||||
08.09.2021, 17:34 | ||||||
Вопросы по данной теме.
Сообщение: https://www.cyberforum.ru/post4061327.html . Все таки как правильно инициализировать строковые переменные командой SET ??? Которые (переменные) в свою очередь могут быть ИЗМЕНЯЕМЫМИ именами файлов, именами директорий, именами масок файлов и т.д. и т.п. . Проясните ПОДРОБНО данный вопрос, пожалуйста. .
0
|
![]() ![]() ![]() |
||||||
11.09.2021, 20:48 [ТС] | ||||||
Jenyok2,
0
|
11.09.2021, 20:48 | |
Помогаю со студенческими работами здесь
117
Ошибки при создании заметки Частые ошибки Частые ошибки winapi Частые ошибки в работе компьютера Частые системные ошибки windows 8 Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
![]() |
||||
Квантовые алгоритмы и обработка строк в Q#
EggHead 07.06.2025
Квантовые вычисления перевернули наше представление о том, как работать с данными, а Q# стал одним из ключевых языков для разработки квантовых алгоритмов. В традиционых системах мы оперируем битами —. . .
|
NUnit и C#
UnmanagedCoder 07.06.2025
В . NET существует несколько фреймворков для тестирования: MSTest (встроенный в Visual Studio), xUnit. net (более новый фреймворк) и, собственно, NUnit. Каждый имеет свои преимущества, но NUnit. . .
|
с++ Что нового?
russiannick 06.06.2025
Продолжаю обзор dev-cpp5. 11. Посмотрев на проекты, предоставленные нам для обучения, становится видно, что они разные по содержащимся файлам
где:
. dev обязательно присутствует
. cpp/ . c один из них. . .
|
WebAssembly в Kubernetes
Mr. Docker 06.06.2025
WebAssembly изначально разрабатывался как бинарный формат инструкций для виртуальной машины, обеспечивающий высокую производительность в браузерах. Но потенциал технологии оказался гораздо шире - она. . .
|
Как создать первый микросервис на C# с ASP.NET Core, step by step
stackOverflow 06.06.2025
Если говорить простыми словами, микросервисная архитектура — это подход к разработке, при котором приложение строится как набор небольших, слабо связанных сервисов, каждый из которых отвечает за. . .
|
Рисование коллайдеров Box2D v2 на Three.js с помощью порта @box2d/core
8Observer8 06.06.2025
Используется порт Box2D v2 под названием @box2d/ core - пакет NPM. Загрузил документацию Box2D v2 на Netlify: https:/ / box2d-v2-docs. netlify. app/ Документацию Box2D v2 можно скачать с официального. . .
|
Как создать стек в Python
AI_Generated 05.06.2025
Как архитектор с более чем десятилетним опытом работы с Python, я неоднократно убеждался, что знание низкоуровневых механизмов работы стеков дает конкурентное преимущество при решении сложных задач. . . .
|
Server-Sent Events (SSE) в Node.js
run.dev 05.06.2025
Потоковая передача данных с сервера прямо в браузер стала повседневной потребностью - от биржевых графиков и спортивных трансляций до чатов и умных дашбордов. Много лет разработчики полагались на. . .
|
Создаем RESTful API на Golang с Fiber
golander 04.06.2025
Я перепробовал десятки фреймворков для создания RESTful API за последние годы, и когда впервые столкнулся с Fiber, понял, что это совсем другой уровень. Нет, я не собираюсь рассказывать сказки о. . .
|
Как работать с куки в ASP.NET Core
UnmanagedCoder 04.06.2025
Когда я впервые начал работать с куки в ASP. NET Core, меня поразило, насколько отличается работа с ними от классического ASP. NET. В Core все стало более декомпозированным - больше нет удобного. . .
|