Форум программистов, компьютерный форум, киберфорум
Наши страницы
Batch (CMD/BAT)
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.65/338: Рейтинг темы: голосов - 338, средняя оценка - 4.65
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,834
Записей в блоге: 16
#1

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

10.01.2013, 15:41. Просмотров 60778. Ответов 106

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

Постим сюда детали, которые Вы получили опытным путем.
Которые считаете уникальными, или могут быть полезными при наборе кода 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.01.2013, 15:41
Ответы с готовыми решениями:

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

Последовательный запуск нескольких BAT-файлов из основного BAT-файла
Доброго времени суток всем... Помогите кто понимает.. Есть bat... @echo off...

Запуск bat-файлов с параметрами, являющимися модификациями принятого запускающим bat-файлом параметра
Написать командный файл, который: • принимает в качестве параметра полное имя...

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

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

106
Smitis
1629 / 338 / 39
Регистрация: 15.10.2012
Сообщений: 529
28.04.2016, 11:04 #81
Цитата Сообщение от YuS_2 Посмотреть сообщение
но раскрываются переменные только в одном set foo... - просто уточнил.
Да, извиняюсь, надо было уточнить о каком set идёт речь. Конечно же - о втором.
1
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,834
Записей в блоге: 16
18.01.2017, 21:57  [ТС] #82
Зацикливание на циклических симлинках

Если нужно рекурсивно просканировать каталог, в котором есть
циклические симлинки (это такие, что ссылаются на каталог выше от текущего),
то dir /a-l /s в этом не поможет:

Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
C:\Users\tfcor>dir /b /adl C:\temp\test
junk
junk2
link
link2
 
C:\Users\tfcor>dir /b /ad-l C:\temp\test
Folder
 
C:\Users\tfcor>dir /b /ad-l /s C:\temp\test
...
C:\temp\test\junk\test\junk\test\junk\test
C:\temp\test\junk\test\junk\test\junk\WaitForIdleInput
C:\temp\test\junk\test\junk\test\junk\1\2
C:\temp\test\junk\test\junk\test\junk\1\2\3
...
т.е. /a-l убирает симлинки только из результатов, в то время как сама
с ключем /s обходит все каталоги, попадаясь на удочку.
0
Victor_Man
0 / 0 / 0
Регистрация: 18.10.2014
Сообщений: 3
05.02.2017, 18:42 #83
Вдруг обнаружил...
Запускаю .cmd из какой-то папки, в .cmd записано:
Windows Batch file
1
If "%CD%\"=="%~dp0"
и далее команда
С удивлением обнаруживаю, что эти переменные не сравниваются, начинаю смотреть:
"%CD%\" = "d:\XXXXXX\"
"%~dp0" = "D:\XXXXXX\"
Т.е. буковки дисков в разных регистрах...вот уж не ожидал

Добавлено через 1 минуту
Что интересно, если перейти в другой каталог, а потом вернуться - буква большая становится.

Добавлено через 16 минут
Переходить пробовал в %TEMP%, с другими папками так не получается.
0
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,834
Записей в блоге: 16
05.02.2017, 19:31  [ТС] #84
If /i "%CD%\"=="%~dp0" ...
0
Victor_Man
0 / 0 / 0
Регистрация: 18.10.2014
Сообщений: 3
05.02.2017, 20:50 #85
Dragokas,
Да, спасибо работает, но придется это зарубить на носу
0
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,834
Записей в блоге: 16
05.02.2017, 20:55  [ТС] #86
Достаточно помнить, что файловые пути в Windows могут иметь разный регистр, но одинаковый физический объект.
А ключи можно увидеть как всегда через
Windows Batch file
1
if /?
0
greg zakharov
Покинул форум
1942 / 818 / 234
Регистрация: 07.05.2015
Сообщений: 1,641
17.02.2017, 12:32 #87
Об определении битности системы

Бытует мнение, что переменная %PROCESSOR_ARCHITECTURE% указывает на архитектуру ЦП компьютера, а потому определяют в командных сценариях битность системы через проверку наличия определенных значений реестра, каталогов, наличие которых свойственно x64 системам, шаманства с WMI и т.д. Есть и более экзотичные способы, но речь не о них. Те, кто ковырялся хоть раз в таких скриптах от Microsoft как setenv.bat (WinSDK) и иже с ним, знают, что в них определение битности системы строится относительно переменной, озвученной в самом начале. Почему? С виду может показаться, что подобная тактика ошибочна, но ведь в Microsoft не с потолка взяли данный подход, и, если капнуть глубже, оказывается, что %PROCESSOR_ARCHITECTURE% задается на этапе установки системы значением поля wProcessorArchitecture структуры SYSTEM_INFO, указывающее в свою очередь на "архитектуру процессора установленной операционной системы" (the processor architecture of the installed operating system). Иначе говоря, если компьютер на базе процессора AMD64, а установленная система 32-битная, %PROCESSOR_ARCHITECTURE% будет иметь значение x86, если 64-битная - значением будет либо x64, либо AMD64, либо IA64.
0
b0gus
253 / 155 / 70
Регистрация: 17.03.2014
Сообщений: 457
19.02.2017, 14:29 #88
Цитата Сообщение от Dragokas Посмотреть сообщение
Способ обхода ошибки
также можно использовать call
Windows Batch file
1
2
3
4
5
@echo off
Setlocal EnableDelayedExpansion
 
Set Var=12345
Call Echo.!Var:~0,1!
0
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,834
Записей в блоге: 16
19.02.2017, 18:56  [ТС] #89
в таком случае ! будет нафиг не нужен. Т.к. %%var%% работает быстрее.
0
b0gus
253 / 155 / 70
Регистрация: 17.03.2014
Сообщений: 457
19.02.2017, 19:05 #90
на выход НЕ пойдёт лишний пробел (в обсуждаемом решении)
Windows Batch file
1
Echo. !Var:~0,1!
0
zb
6 / 6 / 0
Регистрация: 08.05.2017
Сообщений: 55
19.05.2017, 11:56 #91
Windows Batch file
1
echo ( | cmd
консоль начинает добавлять лишний перевод строки в поле вывода команд.
0
alpap
1385 / 1116 / 361
Регистрация: 26.04.2015
Сообщений: 3,982
19.05.2017, 14:17 #92
zb,
да здрасьте!
запуск пустой строки echo( или echo. - привычнее
потом запуск нового cmd с этой переданной пустой строкой
вот и получается две пустые строки.
2
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,834
Записей в блоге: 16
24.07.2017, 19:41  [ТС] #93
Баг модификатора ~s (преобразование имени файла в формат 8.3)

Создайте папку с именем "Темповая папка"
Создайте в ней батник с именем "авп"
Выполните код:
Windows Batch file
1
2
@echo %~fs0
pause
На WinXP:
C:\DOCUME~1\9335~1\0016~1\7AA6~1\80C6~1.CMDп.cmd
На Win7:
C:\Users\Alex\Desktop\D1E9~1\BB43~1.CMD?.cmd
На Win10:
C:\Users\Alex\Desktop\D1E9~1\BB43~1.CMDЀ.cmd
1
YupiRex
183 / 140 / 32
Регистрация: 04.10.2013
Сообщений: 140
25.07.2017, 18:58 #94
Причем для Windows10 - именно на диске С: и дело не букве))
0
Миниатюры
Наиболее частые ошибки, заметки особенностей программинга BAT файлов, баги интерпретатора*   Наиболее частые ошибки, заметки особенностей программинга BAT файлов, баги интерпретатора*  
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,834
Записей в блоге: 16
25.07.2017, 19:05  [ТС] #95
Не совсем понял методику твоего тестирования, и как следствие результаты тоже.
0
YupiRex
183 / 140 / 32
Регистрация: 04.10.2013
Сообщений: 140
25.07.2017, 19:31 #96
Опишу простейший
создаем папку "Темповая папка" в корне диска D: и C: в нее исполняемый файл "авп.BAT"

открываем консоль и запускаем батники:
C:\Users\Yupi>"C:\Темповая папка\авп.BAT"
C:\D1E9~1\B191~1.BATЀ.BAT
C:\Users\Yupi>"D:\Темповая папка\авп.BAT"
D:\Темповая папка\авп.BAT
теперь создадим папки D:\123 и C:\123, положим туда нашу тестовую папку с батником и по очереди подключим эти папки как виртуальный диск и запустим батники

subst e: "c:\123"
"e:\Темповая папка\авп.BAT"
e:\D1E9~1\B191~1.BATЀ.BAT

subst /D e:

subst e: "d:\123"
"e:\Темповая папка\авп.BAT"
e:\Темповая папка\авп.BAT
1
Alikberov
5 / 14 / 4
Регистрация: 03.05.2017
Сообщений: 48
Завершенные тесты: 1
09.09.2017, 12:07 #97
Цитата Сообщение от Dragokas Посмотреть сообщение
Application Crash консоли
Bash
1
(for %%A in () do echo %%A) | Rem
Например, сообщение о критической ошибке, как всегда. У меня в Win 7x64 консоль вообще вылетает.
Код
00007FF7??????D0 FF F3            push        rbx  
00007FF7??????D2 48 83 EC 20      sub         rsp,20h 
00007FF7??????D6 48 83 CB FF      or          rbx,0FFFFFFFFFFFFFFFFh 
00007FF7??????DA 45 33 DB         xor         r11d,r11d 
00007FF7??????DD 4C 8B D3         mov         r10,rbx 
00007FF7??????E0 49 FF C2         inc         r10  
00007FF7??????E3 66 46 39 1C 51   cmp         word ptr [rcx+r10*2],r11w 
00007FF7??????E8 75 F6            jne         00007FF7??????E0 
00007FF7??????EA 48 8B C3         mov         rax,rbx 
00007FF7??????ED 48 FF C0         inc         rax  
00007FF7??????F0 66 45 39 1C 40   cmp         word ptr [r8+rax*2],r11w -> RAX = 0000000000000000 R8  = 0000000000000000 R11 = 0000000000000000
Цитата Сообщение от Dragokas Посмотреть сообщение
Интересно, в XP тоже самое?
Код
Microsoft Windows XP [Версия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.
C:\Documents and Settings\User>C:\test.bat
C:\Documents and Settings\User>
P.S.: Windows'98: (Двойной %% отображается одинарно)
Код
Microsoft(R) Windows 98
   (C)Copyright Microsoft Corp 1981-1999.
C:\WINDOWS>C:\TEST.BAT
C:\>(for %A in ((null)) do echo %A )  | Rem
Имя команды или файла указано неправильно
0
SilverVox
1 / 1 / 0
Регистрация: 05.09.2017
Сообщений: 3
20.09.2017, 12:29 #98
Пролистал всю ветку, вроде подобного не нашел.

Столкнулся с некоторыми особенностями в именах переменных.
Если первый символ имени переменной является цифрой, то возникает путаница. Интерпретатор строку вида %2var% раскрывает как параметр командной строки %2. при этом значение из такой переменной получить можно посредством set 2var , или !2var!

Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@prompt $G
@ECHO off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
 
(SET 24var=Value1)
(SET 32var=Value2)
 
 
ECHO.
ECHO.%24var%
ECHO.%32var%
ECHO.
SET 24var
SET 32var
ECHO.
ECHO.!24var!
ECHO.!32var!
ECHO.
PAUSE>NUL
EXIT /B
0
Dragokas
Эксперт WindowsАвтор FAQ
16945 / 7030 / 855
Регистрация: 25.12.2011
Сообщений: 10,834
Записей в блоге: 16
20.09.2017, 14:47  [ТС] #99
SilverVox, это не баг, а последовательность синтаксического разбора.

P.S. В других языках вообще запрещено именовать так переменные.
1
alpap
1385 / 1116 / 361
Регистрация: 26.04.2015
Сообщений: 3,982
20.09.2017, 17:24 #100
SilverVox,
можно так получить значение
Windows Batch file
1
2
3
set "1var=znach"
cmd/v/c echo %%1var%%
pause
но лучше записывать переменные так:
Windows Batch file
1
2
SET var24=Value1
SET var32=Value2
тогда не будет проблем с их выводом
1
20.09.2017, 17:24
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.09.2017, 17:24

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

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

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


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

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru