Форум программистов, компьютерный форум, киберфорум
Batch (CMD/BAT)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.64/642: Рейтинг темы: голосов - 642, средняя оценка - 4.64
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16

Наиболее частые ошибки, заметки особенностей программинга BAT файлов, баги интерпретатора*

10.01.2013, 15:41. Показов 125691. Ответов 116

Студворк — интернет-сервис помощи студентам
Эта тема - ответвление Тонкости языка, редкие команды и сложные скрипты

Постим сюда детали, которые Вы получили опытным путем.
Которые считаете уникальными, или могут быть полезными при наборе кода 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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.01.2013, 15:41
Ответы с готовыми решениями:

Ошибки при запуске bat-файлов
У меня проблема, что при запуске cmd.exe, что при запуске любого *.bat-файла, появляется такое же сообщение "c:/programПрограмма не...

Наиболее частые значения в таблицах Lua
Ребят, подскажите пожалуйста, не как не могу сообразить, как получить из таблицы наиболее повторяющееся число? например: T1 =...

Как определить количество цветов в подгружаемом рисунке и наиболее частые цвета
Заранее благодарен...

116
2 / 2 / 0
Регистрация: 05.09.2017
Сообщений: 4
20.09.2017, 21:56
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Dragokas Посмотреть сообщение
это не баг, а последовательность синтаксического разбора.
Да, помнится читал об этой-же последовательности в справке по CMD вроде, есть где-то описанно, даже с примерами.
Тем не менее наступал на эти грабли несколько раз за последние 10-ть лет


Добавлено через 2 часа 47 минут
Еще вспомнил одну особенность команды RD.
С тех пор, как перешел на Windows7 (лет пять тому) обнаружил, что RmDir не возвращает код ошибки. (На Windows XP не помню, чтобы сталкивался с этим).
Мне сложно понять почему это происходит и как это объяснить с "научной" точки зрения, но покажу на практическом примере.
Кстати такое поведение наблюдалось не только в RmDir, но не помню точно с какими командами еще.

В данном случае с заведомо неверным параметром, код ошибки будет все-ровно 0.
Windows Batch file
1
2
3
RD NUL
ECHO.!ERRORLEVEL!
ECHO.%ERRORLEVEL%
А так команда вернет код ошибки, если включено отложенное расширение переменных среды
Windows Batch file
1
RD NUL  ||ECHO.!ERRORLEVEL!
Но если нужно относительно ERRORLEVEL реализовать условие, такое решение работает, даже если отложенное расширение переменных среды не включено.
Windows Batch file
1
2
RD NUL ||REM
IF "%ERRORLEVEL%"=="87" ECHO.Failed
Такое ощущение, как будто бы команда выполняется в какой-то отдельной среде.
Но я неуверен, как это правильно можно объяснить.
1
1 / 1 / 0
Регистрация: 15.04.2017
Сообщений: 25
30.11.2017, 13:47
Кусок кода с поиском числа строк и последней строки (с последующем обрезанием ненужного):

Windows Batch file
1
2
3
4
5
6
7
8
set /a NUM=1
     for /f delims^=^ eol^= %%m in ('more +1^< "%%o"') do (
        set /a NUM=!NUM!+1
        echo.!NUM! %%m>i.tmp
     for /f "tokens=1,2* delims= " %%a in (i.tmp) do (
     @echo.%%a %%b>i.tmp
    )
    )
Если в файле 65535 строк и меньше - медленно, но работает, если больше - виснет напрочь.

P.S. Данные с датчика, где первая строка - время в мсек с момента запуска системы.
Как обойти проблему, кроме подключения дополнительного фильтра по размеру файла с учетом минимально возможной (или средней) длины строки - не знаю.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
30.11.2017, 13:50  [ТС]
parmari, вы перепутали тему.
Здесь выкладывают только аналитическую информацию и без вопросов.
0
1 / 1 / 0
Регистрация: 15.04.2017
Сообщений: 25
30.11.2017, 14:07
Число строк 65535 - вполне аналитическая информация. полученная опытным путем. Это 2^16-1, так называемое число Мерсенна. Остальное и правда - лишние подробности.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
01.12.2017, 00:13  [ТС]
parmari, просто не понятно, зачем вы сюда это выложили и как относится к багам интерпретатора.
Под аналитической информацией подразумевается развёрнутый ответ, что вот так и при таком количестве будет виснуть -> следовательно нужно делать вот так и так, или вообще не использовать CMD.
Вы констатируете проблему и хотите получить помощь в её решении? Тогда создайте новую тему, и там вам предложат более быстрые варианты.
А магическое число здесь никак не является решающим фактором. Ваш код трудно назвать оптимизированным.
0
1 / 1 / 0
Регистрация: 15.04.2017
Сообщений: 25
01.12.2017, 13:44
Ладно, в сухом остатке...

На файлах, размер строк которых >65535, при построчной обработке циклом, батник виснет так, словно уходит в бесконечный цикл. Ждать окончания работы - бессмысленно (за ночь ничего не произошло), в то время как файлы меньшего размера (хотя бы на 1 строку!) обрабатывались тем же способом в пределах несколько минут.
Видимо, эта проблема связана с особенностью использования оперативной памяти bat -файлом, поэтому так делать не надо.

Относится ли этот факт к данной теме или нет - на усмотрение модератора - но для меня он был бы в свое время полезен сам по себе.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
01.12.2017, 15:24  [ТС]
В том и дело, что батник не оптимизирован. При таком кол-ве строк, итерации создавать не имеет смысла.
Всё делается проще. find /c /v "" узнаётся кол-во строк. Find /n - добавление номера строки и передача в findstr для получения нужной строки. Затем всего 1 итерация, чтобы отбросить лишнюю часть с номером строки.
В теме с полезными примерами решенных задач подобное есть по ссылкам.
1
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
26.11.2018, 19:17  [ТС]
more.exe и ошибки "Слишком много аргументов в командной строке"

В Windows 10 сломали совместимость со старым синтаксисом more.exe

Windows Batch file
1
2
3
4
C:\Users\Alex>echo 12321 > 1.txt
 
C:\Users\Alex><1.txt more +1
Слишком много аргументов в командной строке.
Теперь нужно явно указывать ключ:
/E Разрешение использования дополнительных возможностей.
Windows Batch file
1
<1.txt more /E +1
2
5 / 5 / 0
Регистрация: 24.11.2014
Сообщений: 48
25.01.2020, 18:37
Dragokas, большое спасибо за пример с UseBackQ (были проблемы с пробелами в пути и имени файла). Я почему-то был уверен, что это касается только содержимого читаемого файла.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
18.10.2020, 00:01  [ТС]
Баг с %~dp0 и планировщиком заданий

Если запустить батник C:\Users\user\desktop\1.bat из-под планировщика,

Windows Batch file
1
echo DP0=%~dp0
выдаст синтаксическую кашу, нечто вроде:

Windows Batch file
1
DP0="C:\Windows\System32"C:\Users\user\desktop\1.bat
Естестественно, обращаться к файлам, лежащим рядом через call "%~dp0file" бесполезно,
через call file тоже, т.к. CD = C:\Windows\System32

Попытаться обойти этот баг можно с помощью:
Windows Batch file
1
call "%0\..\file"
или
Windows Batch file
1
2
cd /d "%0\.."
call file
0
3 / 3 / 0
Регистрация: 24.03.2021
Сообщений: 1
24.03.2021, 20:51
Я даже зарегистрировался, чтобы написать об этом, т.к. не нашёл

Цикл for /r имеет один неприятный баг (или фичу), который может обломать с конечным результатом, т.к. ошибка при этом не выводится. Если в качестве начальной папки после for /r указать раскрываемую переменную из родительского цикла, то она просто не раскроется.

Windows Batch file
1
2
3
4
5
for %%a in ("папка1" "папка2") do (
    for /r "%%~a" %%b in (*.txt) do (
        echo "%%~b"
    )
)
А вот так уже работает, но к сожалению страдает оптимизация:
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
for %%a in ("папка1" "папка2") do (
    call :RecurseFiles "%%~a"
 
)
pause
 
:RecurseFiles
    for /r "%~1" %%b in (*.txt) do (
        echo "%%~b"
    )
exit /b
Ещё одна особенность, хотя скорее всего известная.
Если включено отложенное раскрытие переменных (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
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@echo off
setlocal
set cty=0
set tot=0
 
for %%i in (*.*) do call :processfile %%i
call :logmsg processed %tot% from %cty%
exit /b
 
 
:processfile
set /a tot += 1
call :logmsg "%*"
set /a cty += 1
exit /b
 
 
:logmsg
echo %*
echo %*>> processf.log
exit /b


выводит в конце какую-то лишнюю не понятную строку, частично дублирующую предидущий вывод на экран

потратил почти два дня на отладку пока понял что глюк не связан ни с вызовами подпрограмм, ни с использованием
всяких штук
Windows Batch file
1
2
3
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
IF ERRORLEVEL 1 EXIT /B 129
CHCP 65001 >NUL
которыми успел снабдить исходный скрипт, ни с версией винды...
а с перенаправлением,
с перенаправлением Карл!..

так что желающие могут проверить себя: найти глюк, а потом посмотреть ответ
ответ
Windows Batch file
1
2
3
4
так не правильно:
echo %*>> processf.log
правильно так:
echo %* >> processf.log
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
03.06.2021, 12:09  [ТС]
mark74, поэтому всегда в случаях перенаправления вывода в файл оптимальней писать в обратном порядке, чтобы не зависеть от содержимого буфера:

Windows Batch file
1
>> processf.log echo %*
Ну и в добавок, неплохо бы "закавычить".
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 ???
Которые (переменные) в свою очередь могут быть ИЗМЕНЯЕМЫМИ именами файлов, именами директорий, именами масок файлов и т.д. и т.п.
.
Проясните ПОДРОБНО данный вопрос, пожалуйста.
.
Windows Batch file
1
2
3
4
5
6
7
rem
SET file_NAME1=D:\Work_Test\A001.txt
rem
SET file_NAME2="D:\Work_Test\A002.txt"
rem
SET "file_NAME3=D:\Work_Test\A003.txt"
rem
.
0
1 / 1 / 0
Регистрация: 12.06.2015
Сообщений: 67
11.09.2021, 14:51
Простой вопрос (но пока в интернетах нигде НЕ нашел).
.
Как задать переменной значения 0xd , 0xa , 0xd0xa и вывести эту переменную через echo чтобы был дополнительный перевод строки !???
.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
11.09.2021, 20:48  [ТС]
Jenyok2,
Visual Basic
1
2
3
4
5
6
7
@echo off
SetLocal EnableDelayedExpansion
set lf=^
 
 
echo Hi!lf!world
pause
Только это скорее вопрос в тему: Тонкости языка, редкие команды и сложные скрипты
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.09.2021, 20:48
Помогаю со студенческими работами здесь

Ошибки при создании заметки
Пару дней назад установил Друпал на Xampp, частенько на разных страницах пришет не большие &quot;user warning&quot; но при этом не...

Частые ошибки
Есть проблема и уверен что системная, а не программная. Проблема в том что во время установки программ, они устанавливаются не правильно,...

Частые ошибки winapi
Подскажите, что я делаю не так. Программа запускается без ошибок, но кнопку, которую я создаю, не видно, не видно иконку и изображение,...

Частые ошибки в работе компьютера
Доброго времени суток. Перейду сразу к делу: После включения компьютера никакая программа не работает более 5-10 минут. Сразу закрывается...

Частые системные ошибки windows 8
Что то уж слишком часто начали появляться системные ошибки, почти все разные, ноут HP ENVY M6, ему всего 2 месяца. Подскажите в чем может...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
117
Ответ Создать тему
Новые блоги и статьи
Квантовые алгоритмы и обработка строк в 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 все стало более декомпозированным - больше нет удобного. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
OSZAR »