Форум программистов, компьютерный форум, киберфорум
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. Показов 125755. Ответов 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
 Аватар для b0gus
735 / 333 / 134
Регистрация: 17.03.2014
Сообщений: 836
07.10.2015, 20:44
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Dragokas Посмотреть сообщение
Точка с запятой ( ; ) и запятая ( , ) являются наравне с пробелом - разделителями аргументов.
в этот список можно добавить и знак равно ( = )
0
4339 / 2129 / 661
Регистрация: 26.04.2015
Сообщений: 6,823
09.10.2015, 11:48
Цитата Сообщение от Dragokas Посмотреть сообщение
ведь в одном каталоге не могут существовать папка и файл с одинаковым именем!
- почему?


0
4339 / 2129 / 661
Регистрация: 26.04.2015
Сообщений: 6,823
09.10.2015, 12:08
А мне недавно здесь попался такой код:
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@echo off
setlocal enabledelayedexpansion
chcp 1251
 
set /p k=Введите количество ведущих нулей 
for /L %%j in (1,1,%k%) do set n=!n!0
 
set /p p=Введите путь к директории 
pushd %p%
 
set /a i=1
 
if i lss 10 ( 
for %%f in (*jpg) do (
ren %%f %n%!i!.jpg 
set /a "i=i+1"
)
)
 
else (
for \L %%j in (1,1,%k-1%) do set m=!m!0
for %%f in (*jpg) do (
ren %%f %m%!i!.jpg 
set /a "i=i+1"
)
)
 
pause
, ошибок тут хватает, но очень долго ломал голову, просто не сразу и заметил, с этой строчкой:
Windows Batch file
1
for \L %%j in (1,1,%k-1%) do set m=!m!0
.
0
4339 / 2129 / 661
Регистрация: 26.04.2015
Сообщений: 6,823
09.10.2015, 13:02
Цитата Сообщение от Dragokas Посмотреть сообщение
Вызовет синтаксическую ошибку с прерыванием работы пакетного файла.
Тогда почему вот так:
Windows Batch file
1
2
3
4
5
6
7
8
9
@echo on
Call :Sub "myFile.txt"
goto :eof
 
:Sub
pause
if ""=="" (Set NewFileName=%~1)
pause
Exit /B
,
- работает?
0
Эксперт Python
5437 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
09.10.2015, 18:18
Цитата Сообщение от alpap Посмотреть сообщение
Цитата Сообщение от Dragokas Посмотреть сообщение
ведь в одном каталоге не могут существовать папка и файл с одинаковым именем!
- почему?
Расширение не должно указываться, иначе для ФС это будут разноименные объекты.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
09.10.2015, 20:56  [ТС]
alpap,

Windows Batch file
1
2
md name
echo.>name
0
4339 / 2129 / 661
Регистрация: 26.04.2015
Сообщений: 6,823
10.10.2015, 11:05
Цитата Сообщение от Dragokas Посмотреть сообщение
md name
echo.>name
- так понятно будет отказано в доступе, значит я неправильно понял, прошу прощения.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
21.10.2015, 20:32  [ТС]
Выполнение такой команды проигнорируется, если записано последней строкой батника:

Windows Batch file
1
>NUL pause
"Повесить" консоль в бесконечный цикл (только из батника):

Windows Batch file
1
1 > NUL pause
2
Любознательный
 Аватар для YuS_2
6984 / 2136 / 349
Регистрация: 10.03.2016
Сообщений: 4,927
21.04.2016, 14:53
Цитата Сообщение от Dragokas Посмотреть сообщение
Правильно:
Bash
1
echo !param.%n%!
Неправильно:
Bash
1
echo %param.!n!%
Хотелось бы поправить такое определение, ибо попался вот такой вот случай, где "неправильное" использование приводит к требуемому результату:
Bash
1
2
3
4
5
6
7
8
9
10
11
@echo off
set "foo=b><a><r"
set cr=^
 
 
setlocal enabledelayedexpansion
set foo=%foo:><=!cr!%
echo !foo!
endlocal
echo.
pause
- другие варианты, кроме использования цикла, работают неверно.

И ещё, тоже по теме,особенность консоли:
Пока нигде не попадалось описание (обнаружено опытным путем) отличающейся работы команды set в сценарии с расширением .bat и .cmd:
Bash
1
2
3
4
5
6
7
8
9
@echo off
echo Инструкция z:\z\z\z\z\z, заведомо возвращающая ненулевой код возврата:
echo.
cd "z:\z\z\z\z\z"
echo ERRORLVL=%ERRORLEVEL%
echo.
set n=2
echo ERRORLVL=%ERRORLEVEL%
pause
- один и тот же код запущенный в .bat и .cmd, дает различный вывод во втором errorlevel, т.е. команда set в .bat не сбрасывает errorlevel, а в .cmd - сбрасывает.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
21.04.2016, 15:26  [ТС]
YuS_2, спасибо за замечание и наблюдение.

Действительно, судя по Вашему примеру последовательность раскрытия переменных может действовать и в другом порядке для случая с операцией подстановки.
При чем это работает только для операнда замены.
Если отложенное раскрытие применить для заменяемого операнда или имени переменной, то замены не произойдет.
Windows Batch file
1
2
3
...
set "what=><"
set "foo=%foo:!what!=!cr!%"
Windows Batch file
1
2
3
...
set "var=foo"
set "foo=%!var!:><=!cr!%"
Добавлено через 11 минут
Цитата Сообщение от YuS_2 Посмотреть сообщение
- один и тот же код запущенный в .bat и .cmd, дает различный вывод во втором errorlevel, т.е. команда set в .bat не сбрасывает errorlevel, а в .cmd - сбрасывает.
Да. В этом плане попадалось немного информации. Собственно, поэтому более надежно использовать расширения .cmd, т.к. охватывает больший спектр операций (хотя опять же, автор при написании батника мог учитывать специфику старого формата).
0
Любознательный
 Аватар для YuS_2
6984 / 2136 / 349
Регистрация: 10.03.2016
Сообщений: 4,927
21.04.2016, 19:43
Цитата Сообщение от Dragokas Посмотреть сообщение
последовательность раскрытия переменных может действовать и в другом порядке для случая с операцией подстановки.
Да, это использовалось для конкретной ситуации, надо было заменить пару символов "><" на перевод строки, с которым консоль работает очень своеобразно...
Эта реализация, конечно, имеет свои недостатки и она не очень универсальна, но главное, что она возможна и работает. Поэтому может быть, имеет смысл, заменить определение "правильно-неправильно" на "рекомендуется-не рекомендуется"?

Цитата Сообщение от Dragokas Посмотреть сообщение
Да. В этом плане попадалось немного информации.
Было бы интересно почитать, если остались ссылки...

ещё добавление, на предмет перевода строки:
Пролистал топик и не попался на глаза следующий трюк с текстом:
Windows Batch file
1
2
3
4
5
@echo off
set /p  a= Это любой текст <nul
set /p  =: текст второй строки <nul
echo. : текст третьей строки
pause>nul
- код придумал не я, просто как-то понадобилось через батник склеить несколько строк в одну и в процессе поиска на просторах интернета, попался такой вот вариант. Откуда он взят - не упомню, поэтому первоисточник привести не могу.
0
21.04.2016, 20:15  [ТС]

Не по теме:


Цитата Сообщение от YuS_2 Посмотреть сообщение
Пролистал топик и не попался на глаза следующий трюк с текстом:
На главной в "Тонкости языка" там еще многое подобное есть.
Цитата Сообщение от YuS_2 Посмотреть сообщение
Было бы интересно почитать, если остались ссылки...
На другом форуме. Да и не подтвердилась на тестах та инфа, так что не буду. Было что-то про скорость выполнения и последовательности обработки строк батника. Вообще это лучше узнать у экспертов на dostips com. Они точно знают.

0
1748 / 353 / 41
Регистрация: 15.10.2012
Сообщений: 550
23.04.2016, 23:58
Цитата Сообщение от Dragokas Посмотреть сообщение
Действительно, судя по Вашему примеру последовательность раскрытия переменных может действовать и в другом порядке для случая с операцией подстановки.
Нет! Просто сначала >< заменяется на !cr!, а затем раскрывается !cr!. Последовательность не нарушается.
1
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
24.04.2016, 01:22  [ТС]
1. b><a><r
2. %b!cr!a!cr!r%

Но ведь тогда пришлось бы раскрыть вот такую переменную окружения - b!cr!a!cr!r

Добавлено через 7 минут
В итоге получится !b!cr!a!cr!r! = crcr

Добавлено через 11 минут
Скорее всего вы правы. Последовательность не нарушается. Просто на последней стадии замены срабатывает механизм раскрытия переменных, иначе бы мы увидели другой вывод:
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
@echo off
set b=f
set "foo=!b!><a><r"
set cr=^
 
 
setlocal enabledelayedexpansion
echo "%foo%"
echo "%foo:!b!=!cr!%"
endlocal
echo.
pause
"f><a><r"
" ><a><r"
В первой строке аналогично раскрывается переменная "b".
Во второй строке "b" не раскрывается и поэтому !b! целиком заменяется на пробел (cr).
0
1748 / 353 / 41
Регистрация: 15.10.2012
Сообщений: 550
24.04.2016, 01:46
Цитата Сообщение от Dragokas Посмотреть сообщение
Но ведь тогда пришлось бы раскрыть вот такую переменную окружения - b!cr!a!cr!r
Переменные !cr! будут раскрыты в строке set foo..., после выполнения операции замены >< на !cr! (замена - это тоже раскрытие переменной).
То же без замены:
Windows Batch file
1
2
3
4
5
6
7
8
9
@echo off
set cr=^
 
 
set "foo=b!cr!a!cr!r"
setlocal enabledelayedexpansion
set "foo=%foo%"
echo !foo!
pause
1
Любознательный
 Аватар для YuS_2
6984 / 2136 / 349
Регистрация: 10.03.2016
Сообщений: 4,927
27.04.2016, 09:53
Smitis,
Цитата Сообщение от Smitis Посмотреть сообщение
Windows Batch file
1
2
set "foo=b!cr!a!cr!r"
setlocal enabledelayedexpansion
Разве это правильная последовательность применения !cr!?
0
27.04.2016, 16:40  [ТС]

Не по теме:

YuS_2, смотря что считать правильным. Для рядовых задач Вам такое может вообще никогда не понадобится. А на счет примера выше, просто запустите, и посмотрите, что получится.

0
Любознательный
 Аватар для YuS_2
6984 / 2136 / 349
Регистрация: 10.03.2016
Сообщений: 4,927
27.04.2016, 16:54
Цитата Сообщение от Dragokas Посмотреть сообщение
на счет примера выше, просто запустите, и посмотрите, что получится.
Да нет, общий смысл и то, что переменной, которая раскрывается далее за setlocal, присваивается строка - это понятно. Смутило другое:
Цитата Сообщение от Smitis Посмотреть сообщение
Переменные !cr! будут раскрыты в строке set foo...
но там ведь тоже:
Цитата Сообщение от Smitis Посмотреть сообщение
set "foo=b!cr!..."
ну, да ладно... в принципе, ясно, что требовалось получить, просто небольшое недопонимание случилось у меня.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18025 / 7728 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
27.04.2016, 17:03  [ТС]
Последовательность не ламается:

1. set "foo=%foo%"
%foo% - заменяется на значение переменной foo, а это - b!cr!a!cr!r
2. Поскольку в данный момент уже включен режим отложенного раскрытия переменных, то в добавок после этого второй операцией идет раскрытие переменных внутри !!
Итого результат - b a r

Поэтому оба синтаксиса годятся, просто используются в разных ситуациях в зависимости от конкретного назначения (задания).
0
Любознательный
 Аватар для YuS_2
6984 / 2136 / 349
Регистрация: 10.03.2016
Сообщений: 4,927
27.04.2016, 22:07
Цитата Сообщение от Dragokas Посмотреть сообщение
Поэтому оба синтаксиса годятся
Эмм, если это для меня было, то лишнее, смысл сценария достаточно понятен.
Всего лишь, имел ввиду неточность ссылки:
Цитата Сообщение от Smitis Посмотреть сообщение
Переменные !cr! будут раскрыты в строке set foo...
ибо в одном сценарии, это "set foo..." встречается два раза:
Цитата Сообщение от Smitis Посмотреть сообщение
Windows Batch file
1
2
3
set "foo=b!cr!a!cr!r"
...
set "foo=%foo%"
но раскрываются переменные только в одном set foo... - просто уточнил.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.04.2016, 22:07
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Повышаем производительность игры на Unity 6 с GPU Resident Drawer
GameUnited 11.06.2025
Недавно копался в новых фичах Unity 6 и наткнулся на GPU Resident Drawer - штуку, которая заставила меня присвистнуть от удивления. По сути, это внутренний механизм рендеринга, который автоматически. . .
Множества в Python
py-thonny 11.06.2025
В Python существует множество структур данных, но иногда я сталкиваюсь с задачами, где ни списки, ни словари не дают оптимального решения. Часто это происходит, когда мне нужно быстро проверять. . .
Работа с ccache/sccache в рамках C++
Loafer 11.06.2025
Утилиты ccache и sccache занимаются тем, что кешируют промежуточные результаты компиляции, таким образом ускоряя последующие компиляции проекта. Это означает, что если проект будет компилироваться. . .
Настройка MTProxy
Loafer 11.06.2025
Дополнительная информация к инструкции по настройке MTProxy: Перед сборкой проекта необходимо добавить флаг -fcommon в конец переменной CFLAGS в Makefile. Через crontab -e добавить задачу: 0 3. . .
Изучаем Docker: что это, как использовать и как это работает
Mr. Docker 10.06.2025
Суть Docker проста - это платформа для разработки, доставки и запуска приложений в контейнерах. Контейнер, если говорить образно, это запечатанная коробка, в которой находится ваше приложение вместе. . .
Тип Record в C#
stackOverflow 10.06.2025
Многие годы я разрабатывал приложения на C#, используя классы для всего подряд - и мне это казалось естественным. Но со временем, особенно в крупных проектах, я стал замечать, что простые классы. . .
Разработка плагина для Minecraft
Javaican 09.06.2025
За годы существования Minecraft сформировалась сложная экосистема серверов. Оригинальный (ванильный) сервер не поддерживает плагины, поэтому сообщество разработало множество альтернатив. CraftBukkit. . .
Dapper - лучший среди микроORM под C#
UnmanagedCoder 09.06.2025
Знаете, в мире ORM-инструментов для . NET существует негласная иерархия. На вершине массивных фреймворков возвышается Entity Framework - неповоротливый, но всемогущий. А в категории легковесных. . .
Сравнение GCC 14 и Clang 18 компиляторов C для HPC
bytestream 08.06.2025
В высокопроизводительных вычислениях (HPC) выбор компилятора - это ход, способный радикально изменить производительность всей системы. Работая последние 15 лет с критическими HPC-системами, я видел. . .
Всё о конфигурации ASP.NET Core
stackOverflow 08.06.2025
Старый добрый web. config, похоже, отправился на пенсию вместе с классическим ASP. NET. За годы работы с различными проектами я убедился, что хорошо организованная конфигурация – это половина успеха. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
OSZAR »