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

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

16.10.2012, 06:56. Показов 246030. Ответов 97

Студворк — интернет-сервис помощи студентам
Тема для пользователей высокого уровня подготовки.

Здесь можете размещать:
  • Ваши статьи;
  • Ссылки на другие статьи (допускаются статьи на английском языке);
  • Редкие ошибки, выдаваемые интерпретатором, способы их устранения/либо причины возникновения.
  • Недокументированные и особые трюки работы с файловой системой, устройствами и т.п.
  • Разрешено обсуждение выложенных здесь материалов (в последствии будут выделены в отдельную тему);
  • Запрещено обсуждение новичками проблем работы с CMD, где вероятная причина - банальная синтаксическая ошибка.


Статьи и тонкости языка:
Основы
  • FAQ по файлам BAT/CMD (статья) ссылка
  • Командная строка Windows (статья) ссылка
  • Особенности реализации командного процессора cmd.exe операционных систем WinNT (статья) сайт
  • Циклические операции и примеры (статья) эта тема
  • Принцип составления однострочных команд Batch (статья) эта тема
Автозапуск
  • Запуск Bat-файла как службы Эта тема
  • Выполнение командного файла перед входом в систему Эта тема
Безопасность и права
  • Элевация прав запуска BAT-файла (отображается диалог контроля учетных записей UAC) ссылка
  • Как запустить командную строку от имени администратора. эта тема
Интерфейс
  • Переключение языка вывода команд консоли на английский ссылка
КомментарийМатематика
  • Деление с выводом дробной части на батниках ссылка
  • Деление через строковую математику (для делимого, превышающего тип данных signed long int) ссылка
  • Получение 16-ричного представления числа эта тема
  • Получение кода символа по таблице ASCII из числового значения byte эта тема
  • Перевод чисел из десятеричной системы в любую (2-16) эта тема
  • Логические операции сравнения для чисел, превышающих арифметику CMD эта тема
Операционная система, реестр
  • Почему нежелательно запускать BAT из 32-битной среды в 64-разрядной системе. ссылка
  • Функции чтения/записи ключа реестра с отображением уровня ошибки ссылка
Переменные и аргументы
  • Подстановка значения переменной в имя или параметр другой переменной эта тема
  • Перебросить значение через локаль эта тема
  • Часто задаваемые вопросы по использованию аргументов командной строки (статья) сайт
  • Получение рабочего каталога на определенном диске эта тема
  • Undocumented Dynamic variables (недокументированные способы раскрытия переменных среды) эта тема
ПотокиПроцессы
  • Получение PID, имени, пути и параметров запуска процесса эта тема
Связь с другими языками программирования и средами, комбинированные батники

  • -- JScript
  • Скомбинированный файл CMD + JS (WSH) эта тема
  • Выполнение JS кода через mshta.exe эта тема
    -- VBScript
  • Передача значения из BAT-сценария в VBS-скрипт эта тема
  • Метод возврата значения из VBS-скрипта в BAT-сценарий эта тема
  • Получение ErrorLevel из команды CMD в переменную VBS-скрипта тема
    -- Реестровый ключ
  • Способ хранения ключа реестра внутри бат-файла эта тема
    -- Ресурсы внутри BAT-файла
  • Распаковка текстовой информации, заданной меткой в файле CMD, во внешний файл тема
  • Встраивание ресурсов в БАТ-файл тема
    -- Другое:
  • Комбинированный файл CMD + KIXTART
  • Объектно-ориентированное программирование на bat ссылка
Текстовые операции и работа с "массивами"
  • Вывод текста без переноса на новую строку (статья) эта тема
  • Чтение текста из файла без пропуска пустых строк эта тема
  • Экранировать восклицательный знак эта тема
  • Получить последний токен в заданной строке эта тема
  • Урезать в строке справа лишние пробелы или другие подряд идущие символы эта тема
  • Получение символов BackSpace (0x08) и Esc (0x27) в переменную эта тема
  • Получение символов CR (0x0D) и LF (0x0A) в переменную этот пост
  • Функция для работы с массивами эта тема
  • Считывание файла в псевдомассив с учетом пустых строк эта тема
  • Функция правильного выравнивания текста по знакам табуляции эта тема
  • Способ передачи в бат-файл параметра содержащего символы & и последующей обработки полученного значения эта тема
Циклы
  • Подстановка переменной в роле модификатора для цикла эта тема
  • Разбиение строки на токены, если разделитель - кавычка эта тема
Файловые операции
  • Объединить 2 файла (сохранив результаты в одном из них) эта тема
  • Получение информации о размере папки эта тема

References, Special Manuals, Книги для High Level Users:
  • Command-line Reference (Microsoft Tech-Net)
  • Недокументированные и малоизвестные возможности Windows XP (книга)
  • Описание встроенных консольных утилит и команд для различных версий ОС dx21.com CMD-Reference

Баги интерпретатора CMD и встроенных команд
Планируется разместить:
Rem не всегда является командой начала комментария
Создание и удаление точек повторной обработки сайт


Если у Вас возникли вопросы, создайте новую тему.
17
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.10.2012, 06:56
Ответы с готовыми решениями:

Тонкости языка С,define
Здравствуйте. Разбираюсь с одной либой для hd44780, есть вопрос по поводу использования define'ов. Вот отрывок: #define GLUE(a,...

Поддерживает ли встроенный сервер PHP скрипты языка Perl?
В PHP существует встроенный сервер. Создаю файл index.html с формой и файл test.pl для ее обработки. Хотел протестировать на встроенном...

Команды языка PCL
Люди добрые! Подскажите пожалуйста, что написать в конфигурационном файле sets.txt, чтобы принтер hp2200 делал отступ слева на...

97
Клюг
 Аватар для Charles Kludge
7677 / 3192 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
16.10.2012, 14:42
Collection of undocumented and obscure features in various MS-DOS versions - переводить лень.

 Комментарий модератора 
К сожалению, в текущей версии интерпретатора практически все описанные вариации команд не работают или вообще не существуют такие утилиты.
2
Клюг
 Аватар для Charles Kludge
7677 / 3192 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
18.10.2012, 12:20
Дык, An A-Z Index of the Windows CMD command line, весьма подробно, например:
Advanced usage - CALL SET
The CALL SET syntax allows a variable substring to be evaluated, read the CALL page for more detail on this technique:
Bash
1
2
3
4
5
SET start=10
 SET length=9
 SET string=The quick brown fox jumps over the lazy dog
 CALL SET substring=%%string:~%start%,%length%%%
 ECHO (%substring%)
Hidden features of Windows batch files - отсюда выудил, например, как сделать inline-комментарий:
Bash
1
echo %DATE% &::однострочный комментарий
 Комментарий модератора 
Весьма удобная фишка!
3
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
27.10.2012, 01:54  [ТС]
Способ хранения ключа реестра внутри бат-файла

Bash
1
2
3
4
5
6
7
8
9
REGEDIT4
 
; @ECHO OFF
; CLS
; REG IMPORT "%~f0"
; EXIT
 
[HKEY_CURRENT_USER\Software\Test]
"TestVal"="Succeeded"
Запускает сам себя и импортирует ключ в реестр.
; в CMD интерпретируется как знак пробела.

by Rob Vanderwoude. Спасибо за ссылочку: Charles Kludge.
8
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
13.11.2012, 01:44  [ТС]
На тему "Сложные скрипты" (для "разбора полетов"):

Hex_Dump
Bash
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
@echo off
:hexDump [/option]... file - dump a file in hex format
::
::  Displays the content of a binary file using a pair of hexadecimal digits
::  for each byte. By default the ouput displays 16 bytes per line, with the
::  bytes (hexadecimal pairs) delimited by a space.
::
::  The format of the dump can be modified by the following case insensitive
::  options:
::
::    /BblockSize   The blockSize after the /B specifies the number of bytes
::                  to print in each block. If the blockSize is <= 0 then /C,
::                  /D, /E, /A and /O options are ignored and the bytes are
::                  output in a continuous stream without any delimiters or
::                  linebreaks.
::                  The default blockSize is 1.
::
::    /CblockCount  The blockCount after the /C specifies the number of blocks
::                  to include on each line of output.
::                  The default blockCount is 16.
::
::    /DbyteDelim   The byteDelim after the /D specifies the delimiter string
::                  to use between bytes within a block.
::                  The default byteDelim is undefined (no delimiter)
::
::    /EblockDelim  The blockDelim after the /E specifies the delimiter string
::                  to use between blocks within a line.
::                  The default blockDelim is "/E " (a single space)
::
::    /SstartOffset The startOffset after the /S specifies the number of bytes
::                  to skip before displaying bytes.
::                  The default startOffset is 0.
::
::    /Nlength      The length after the /N specifies the total number of
::                  bytes to display after the startOffset. The default is to
::                  display up until the end of the file.
::
::    /A            Append the ASCII representation of the bytes to the end
::                  of each line. Non-printable and extended ASCII characters
::                  are displayed as periods.
::
::    /O            Prefix each line with the starting offset of the line in
::                  hexadecimal notation.
::
::    /H            Display hexDump help
::
::  Each option must be entered as a separate argument. Numeric components to
::  options may be specified using any numeric expression supported by SET /A.
::  The option defaults may be modified by presetting a hexDumpDefaults
::  variable.
::
  setlocal enableDelayedExpansion
  set /a blockSize=1, blockCount=16, startOffset=0
  set ascii=
  set offset=
  set len=
  set opts=
  set byteDelim=
  set "blockDelim= "
  set endDefault=
  for %%a in (!hexDumpDefaults! // %*) do (
    if not defined opts (
      set "arg=%%~a"
      if "!arg:~0,1!"=="/" (
        if defined endDefault shift /1
        set "opt=!arg:~1,1!"
        if /i "!opt!"=="B" set /a blockSize=!arg:~2!
        if /i "!opt!"=="C" set /a blockCount=!arg:~2!
        if /i "!opt!"=="D" set "byteDelim=!arg:~2!"
        if /i "!opt!"=="E" set "blockDelim=!arg:~2!"
        if /i "!opt!"=="S" set /a startOffset=!arg:~2!
        if /i "!opt!"=="N" set /a len=!arg:~2!
        if /i "!opt!"=="A" set "ascii=  "
        if /i "!opt!"=="O" set offset=TRUE
        if /i "!opt!"=="H" set "opts=TRUE" & goto :hexDump.help
        if /i "!opt!"=="/" set endDefault=true
      ) else set opts=TRUE
    )
  )
  if "%~1"=="" goto :hexDump.help
  if not exist %1 (
    echo ERROR: File not found >&2
    exit /b 1
  )
  set fileSize=%~z1
  if defined len (
    set /a "endOffset = startOffset + len"
    if !endOffset! gtr %fileSize% set endOffset=%fileSize%
  ) else set endOffset=%fileSize%
  if defined offset set offset=%startOffset%
  if %blockSize% lss 1 (
    set /a "blockSize=0, blockCount=2000"
    set "ascii="
    set "offset="
    set "byteDelim="
    set "blockDelim="
  )
  set dummy="!temp!\hexDumpDummy%random%.txt"
  <nul >%dummy% set /p ".=A"
  set dummySize=1
  for /l %%n in (1,1,32) do (if !dummySize! lss %endOffset% set /a "dummySize*=2" & type !dummy! >>!dummy!)
  set /a "pos=0, cnt=0, skipStart=startOffset+1, lnBytes=blockSize*blockCount"
  set "off="
  set "hex="
  set "txt=%ascii%"
  set map= ^^^!^"#$%%^&'^(^)*+,-./0123456789:;^<=^>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^^^^_`abcdefghijklmnopqrstuvwxyz{^|}~
  set hexMap=0123456789ABCDEF
  ::DEFINE INTERNAL MACRO USED SOLELY BY THIS FUNCTION
  setlocal disableDelayedExpansion
 
  set LF=^
 
 
  ::Above 2 blank lines are required - do not remove
 
  set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
 
  set callMacro=for /f %%a in
 
  set addChar= do (%\n%
    set "byte=%%~a"%\n%
    if "!byte!"=="2space" set "byte=  "%\n%
    if defined ascii if "!byte!" neq "  " (%\n%
      set /a "d=0x!byte!-32"%\n%
      if !d! lss 0 set d=14%\n%
      if !d! gtr 94 set d=14%\n%
      for %%d in (!d!) do set txt=!txt!!map:~%%d,1!%\n%
    )%\n%
    if %blockSize% gtr 0 set /a pos+=1%\n%
    if !pos!==%blockSize% set /a "pos=0, cnt+=1"%\n%
    if not !cnt!==!blockCount! (%\n%
      if !pos!==0 (set "hex=!hex!!byte!!blockDelim!") else set "hex=!hex!!byte!!byteDelim!"%\n%
    ) else (%\n%
      set "hex=!hex!!byte!"%\n%
      set cnt=0%\n%
      if defined offset (%\n%
        set off=%\n%
        set dec=!offset!%\n%
        for /l %%n in (1,1,8) do (%\n%
          set /a "d=dec&15,dec>>=4"%\n%
          for %%d in (!d!) do set "off=!hexMap:~%%d,1!!off!"%\n%
        )%\n%
        set "off=!off!: "%\n%
        set /a offset+=lnBytes%\n%
      )%\n%
      set "ln=!off!!hex!!txt!"%\n%
      if %blockSize%==0 (^<nul set /p ".=!ln!") else echo !ln!%\n%
      set hex=%\n%
      set "txt=%ascii%"%\n%
    )%\n%
  )
 
   ::END OF MACRO DEFS
  setlocal enableDelayedExpansion
  for /f "eol=F usebackq tokens=1,2 skip=1 delims=:[] " %%A in (`fc /b "%~dpf1" %dummy%`) do (
    set /a skipEnd=0x%%A && (
      if !skipEnd! geq %startOffset% if !skipStart! leq %endOffset% (
        for /l %%n in (!skipStart!,1,!skipEnd!) do %callMacro% ("41") %addChar%
        %callMacro% ("%%B") %addChar%
        set /a skipStart=skipEnd+2
      )
    )
  )
  for /l %%n in (%skipStart%,1,%endOffset%) do %callMacro% ("41") %addChar%
  if %blockSize%==0 if defined hex (<nul set /p ".=!hex!") & set hex=
  for /l %%n in (1,1,%lnBytes%) do if defined hex %callMacro% ("2space") %addChar%
  del %dummy%
  exit /b
  ::-------------------------------------------------------
  :hexDump.help
    setlocal disableDelayedExpansion
    echo:
    set file="%~f0"
    set beg=
    for /f "tokens=1,* delims=:" %%a in ('findstr /n /r /i /c:"^:hexDump " %file%') do (
      if not defined beg set beg=%%a
    )
    set end=
    for /f "tokens=1 delims=:" %%a in ('findstr /n /r /c:"^[^:]" %file%') do (
      if not defined end if %beg% LSS %%a set end=%%a
    )
    for /f "tokens=1,* delims=[]:" %%a in ('findstr /n /r /c:"^ *:[^:]" /c:"^::[^:]" /c:"^ *::$" %file%') do (
      if %beg% LEQ %%a if %%a LEQ %end% echo: %%b
    )
exit /b 0


Добавлено через 1 час 56 минут
Выполнение полноценного WMI через CMD:
(используется обертка HTA+JavaScript)

Bash
1
2
3
4
5
6
7
8
9
10
11
12
@echo off
setlocal
 
for /f "usebackq delims=" %%i in (
    `@"%systemroot%\system32\mshta.exe" "javascript:try {new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(new String(new Enumerator(new ActiveXObject('WbemScripting.SWbemLocator').ConnectServer('.', 'root\\cimv2').ExecQuery('SELECT LocalDateTime FROM Win32_OperatingSystem WHERE Primary = True')).item().LocalDateTime).substr(0, 8 + 6))}; catch (e){}; close();" ^
    1^|more`
) do set sDateTime=%%i
 
echo %sDateTime%
 
endlocal
exit /b 0
Добавлено через 16 часов 49 минут
Метод возврата значения из VBS-скрипта в BAT-сценарий
(на примере скрипта, который ожидает, пока не будет подключен съемный диск)

Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@echo off
(
echo For Each n in CreateObject^("Scripting.FileSystemObject"^).Drives
echo if n.DriveType = 1 And n.IsReady = True Then
echo if Not n.DriveLetter = "A" And Not n.DriveLetter = "B" Then Wscript.Echo n.DriveLetter
echo End if
echo Next
) >"%temp%\_.vbs"
:seek
for /f %%a in ('cscript //nologo "%temp%\_.vbs"') do set FLASH=%%a:
if "%FLASH%"=="" ( 
   set /p="."<nul
   ping -n 2 127.0.0.1 >nul
   goto :seek
)
del "%temp%\_.vbs"
Echo %Flash%
pause
Передача значения из BAT-сценария в VBS-скрипт

Bash
1
start "" wscript.exe //nologo VBScript.vbs "My file.txt"
Содержимое VBScript.vbs
Visual Basic
1
2
3
4
5
if wscript.Arguments.Count=0 then 
    Msgbox "Аргументы не переданы"
  else
    Msgbox "Значение первого переданного аргумента = " & wscript.Arguments(0)
end if
Получение ErrorLevel из команды CMD в переменную VBS-скрипта здесь

Вынесение кода, заданного меткой в скомбинированном BAT-файле можно увидеть здесь
2
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
24.11.2012, 03:55  [ТС]
Объединить 2 файла (сохранив результаты в одном из них)

В конец результирующего файла помещает управляющий символ (&1A) вместо переноса каретки.

Bash
1
copy %1+%2
2-й файл присоединится к 1-му. Результат сохранится в 1-м файле.

Bash
1
copy %2+%1
1-й файл присоединится ко 2-му. Результат запишется во 2-м файле.

Цитата Сообщение от Smitis Посмотреть сообщение
Уточнение 3961893
Цитата Сообщение от Dragokas Посмотреть сообщение
В конец результирующего файла помещает управляющий символ (&1A) вместо переноса каретки
Есть ключи /a и /b для копирования, соответственно, текстовых и бинарных файлов. При копировании с ключом /a в конец результирующего файла всегда добавляется символ с кодом &1A (это управляющий символ EOT - End Of Text). Кроме того, текстовые файлы будут обрезаны до символа EOT, если он в них встретится. Бинарные файлы копируются "as is". Без ключей /a и /b команда copy включает некий AI, пытаясь определить текстовый файл или бинарный. Результаты этого AI не всегда адекватны. Поэтому, хорошей привычкой может быть всегда использовать ключ /b, даже при копировании текстовых файлов (дабы избежать появление последнего "мусорного" символа).
2
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
10.12.2012, 00:48  [ТС]
Экспериментировал тут с пользовательскими дескрипторами потоков. Добился такого:

Перенаправить потоки вывода StdOut + StdError батника во внешний файл
Bash
1
2
3
4
5
6
7
8
@echo off
::Потоки вывода по-умолчанию всех последующих команд будут перенаправляться в файл out1.txt
Echo. 1>&3 2>&4 3>out1.txt 4>&3
::Создаем вывод в StdOut (дескриптор № 1)
Echo testing
::Имитируем ошибку - вывод в StdError + StdOut (дескрипторы 2, 1)
copy zz:\
pause>con
В результате получится файл out1.txt с текстом testing, сообщениями от команды Copy.
Для принудительного вывода потока на экран следует воспользоваться конструкцией > con
как показано в последней строке.

Еще одним способом является запуск батника через консоль с явным перенаправлением:
Bash
1
batnik.bat 1>out1.txt 2>&1
либо вариант через двойной запуск батника:
Bash
1
2
3
4
5
6
7
8
@echo off
if "%1"=="" (
  Echo Working...
  Call "%~dpnx0" 0 1>nul 2>&1
  Echo Ready...
  Goto :eof
)
::Здесь далее Ваш код
Для дозаписи лога в файл достаточно удвоить знак >>
Bash
1
batnik.bat 1>>out1.txt 2>&1
Для зануления, как всегда можно воспользоваться перенаправлением на устройство Nul
Bash
1
batnik.bat 1>nul 2>&1
Конструкция 2>&1 присоединяет поток вывода ошибок (2) к потоку вывода информационных сообщений (1).
Немного больше информации о потоках: http://microsin.ru/content/view/127/1/
4
887 / 189 / 16
Регистрация: 18.07.2011
Сообщений: 260
13.12.2012, 16:07
Перебросить значение через локаль
Есть такой приём:
Bash
1
2
3
4
5
6
setlocal enabledelayedexpansion &:: Локаль начала действовать
set A=Bla-Bla-Bla &:: Присвоение внутри локали
endlocal&set B=%A% &:: Сначала происходит преобразование переменных в значения (локаль ещё действует), 
:: потом выполняется преобразованая команда, т.е. отключается локаль, а потом происходит присвоение,
:: при этом B находится за пределами локали
echo %B% ::& Вуаля!
То же самое, но без комментариев.
Bash
1
2
3
4
setlocal enabledelayedexpansion
set A=Bla-Bla-Bla
endlocal&set B=%A%
echo %B%
4
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
16.12.2012, 03:36  [ТС]
Скомбинированный файл CMD + JS (WSH)
Автор: amel27 (OSZone)

(на примере скрипта, который копирует файл из одного места в другое)
Bash
1
2
3
4
5
6
7
8
9
@set @x=0 /*;
@set $f=C:\1\2003.GDB;
@set $d=C:\2\2003.GDB;
 
@cscript //nologo /e:jscript "%0" "%$f%" "%$d%";
@exit /b
 
*/new ActiveXObject("shell.Application").NameSpace(WScript.Arguments(1)).CopyHere(WScript.Arguments(0),16);
//
1
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
21.12.2012, 17:14  [ТС]
Деление с выводом дробной части на батниках
Как известно в бат-файлах есть только операция целочисленного деления
и получения остатка от деления. Получить дробное число нельзя. Решил восполнить этот пробел:
Bash
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
::Деление с выводом дробной части на батниках
@echo on
::Введите ограничение точности (знаков после точки)
::Не более 8 знаков !!! (ограничение арифметики от -2147483647 до 2147483647.)
Set /A Znak=8
::Введите делимое
Set /A n1=7
::Введите делитель
Set /A n2=6
::Разделитель целой и дробной части
Set Delim=.
 
Set /A nC=n1/n2
Set /A nO=%n1% %% %n2%
if %nO%==0 Goto :ret
Set /A nD=nO
For /L %%A in (1,1,%Znak%) do Set /A nD*=10
Set /A nD=nd/n2
:Trim0
Set /A rest=%nd% %% 10
if %rest%==0 (Set /A nd/=10& Goto :Trim0)
Set nd=%Delim%%nD%
:ret
Echo %nC%%nD%
pause>nul
Алгоритм получения дробной части:
Остаток от деления * (10^(знаков после запятой)) / делитель.
Потом убираются лишние концевые нули у дробной части.
1
1748 / 353 / 41
Регистрация: 15.10.2012
Сообщений: 550
30.12.2012, 16:06
Комбинированный файл CMD + KIXTART
Code
1
2
3
4
5
6
7
8
9
;@echo off
;echo CMD part1
;kix32 "%~f0" %*
;echo CMD part2
;goto:eof
break on
$=setascii("on")
"KIXTART part"
?
Во втором примере используется комбинированный скрипт, для получения системных даты и времени, не зависимо от региональных настроек. Файл GetDT.cmd:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
;@echo off
;if "%~1" == "" goto nopar
;for /f %%i in ('kix32 "%~f0"') do set %1=%%i
;goto:eof
;:nopar
;:: Если переменная не задана, использует _dt_
;for /f %%i in ('kix32 "%~f0"') do set _dt_=%%i
;goto:eof
 
break on
$=setascii("on")
$time = @time
$date = @date
left($date,4) "-" substr($date,6,2) "-" substr($date,9,2)
"-" left($time,2) "-" substr($time,4,2) "-" substr($time,7,2)
Использование из другого cmd:
Code
1
2
3
4
@echo off
:: Переменной dt будет присвоено значение вида YYYY-MM-DD-HH-MM-SS
call GetDT dt
echo %dt%
П.С.
Скриптовый язык kixtart в настоящее время незаслуженно забыт. А ведь когда-то MS даже включала его в ResourceKit
1
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
07.01.2013, 03:50  [ТС]
Получение информации о размере папки
Взято с OSZONE, переделано мной для совместимости с ОС без локализации (EN).

Развернуть код...

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
Set DirProg=l:\bash\test
 
Call :GetTemporaryName tmpfile
 
Dir "%DirProg%" /-C /S /A:-D>"%tmpfile%"
for /f %%A in ('find /v /c "" ^< "%tmpfile%"') do Set /A Count=%%A
Set /A Count-=2
For /F "tokens=1-3" %%a IN ('more +%Count% ^< "%tmpfile%"') Do Set dirsize=%%c& Goto :DirSizeExt
:DirSizeExt
Del "%tmpfile%"
 
Set /a dirsizeT=dirsize+0
If Not "%dirsizeT%"=="%dirsize%" Echo Число %dirsize% слишком велико для обработки в CMD&Pause>nul&Exit
Set kb=1024
Set /a mb=kb*kb, gb=kb*kb*kb, dirsizeKB=dirsize/kb, ostKB=dirsize%%kb*100/kb, dirsizeMB=dirsize/mb, ostMB=dirsize%%mb*100/mb
::Set /a dirsizeGB=dirsize/gb, ostGB=dirsize%%gb*10/gb
Echo %dirsize% Б
Echo %dirsizeKB%,%ostKB% кБ
Echo %dirsizeMB%,%ostMB% МБ
::Echo %dirsizeGB%,%ostGB% ГБ
pause
Exit /B
 
:GetTemporaryName %varName%
set sTempName=%temp%\temp%random%.tmp
if exist "%sTempName%" (goto :GetTemporaryName) else (set %1=%sTempName%)


upd.
Еще более коротко:
Windows Batch file
1
2
3
4
5
@Echo Off
SetLocal enabledelayedexpansion
Set Folder=l:\Bash
For /F "tokens=1-3" %%a IN ('Dir "%Folder%" /-C/S/A:-D') Do Set DirSize=!n2!& Set n2=%%c
Echo Size of %Folder% is %DirSize% Bytes.
.
Оригинальная функция
Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Echo Off
SetLocal enabledelayedexpansion
Set DirProg=l:\bash\test
 
For /F "skip=4 tokens=1-3" %%a IN ('Dir "%DirProg%" /-C /S /A:-D') Do (
    If !flag!==1 Set dirsize=%%c
    If "%%b"=="файлов:" (Set flag=1) Else (Set flag=0)
)
Set /a dirsizeT=dirsize+0
If Not "%dirsizeT%"=="%dirsize%" Echo Число %dirsize% слишком велико для обработки в CMD&Pause>nul&Exit
Set kb=1024
Set /a mb=kb*kb, gb=kb*kb*kb, dirsizeKB=dirsize/kb, ostKB=dirsize%%kb*100/kb, dirsizeMB=dirsize/mb, ostMB=dirsize%%mb*100/mb
Rem Set /a dirsizeGB=dirsize/gb, ostGB=dirsize%%gb*10/gb
Echo %dirsize% Б
Echo %dirsizeKB%,%ostKB% кБ
Echo %dirsizeMB%,%ostMB% МБ
Rem Echo %dirsizeGB%,%ostGB% ГБ
Pause>nul
2
Модератор
Эксперт JS
 Аватар для Eva Rosalene
5241 / 2115 / 416
Регистрация: 06.01.2013
Сообщений: 4,846
07.01.2013, 15:13
Функция для работы с массивами
Может быть, кому нибудь будет полезно. Это пример функции для работы с массивами, на случай если стандартный array не работает.

Развернуть код...
Bash
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@echo off
setlocal enabledelayedexpansion
call :arrays new H 10
call :arrays set H 8 5
call :arrays get H 8 last
echo %last%
pause>nul
exit
 
:arrays
@echo off
set function_name=%~1
set massive_name=%~2
set array_position=%~3
set last_arg=%~4
 
if "!function_name!"=="" (
 exit /b
)
if !function_name!==new (
 if "!array_position!"=="" (
  exit /b
 )
)
if !function_name!==set (
 if "!last_arg!"=="" (
  exit /b
 )
)
if !function_name!==get (
 if "!last_arg!"=="" (
  exit /b
 )
)
 
if !function_name!==new (
 call :massive_create
 )
if !function_name!==set (
 call :element_set
 )
if !function_name!==get (
 call :element_get
 )
exit /b
 
:massive_create
FOR /L %%a IN (1,1,!array_position!) DO (
 set %massive_name%%%a=0
 )
exit /b
:element_set
set %massive_name%%array_position%=%last_arg%
exit /b
:element_get
set %last_arg%=!%massive_name%%array_position%! 
exit /b


Прим. от Dragokas: нашел еще похожую тему на хабре: http://habrahabr.ru/post/75951/
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
07.01.2013, 23:11  [ТС]
Получение PID, имени, пути и параметров запуска процесса

1. Получить PID, Path, Parameters, зная имя процесса
2. Получить имя, Path, Parameters, зная ID процесса
3. Получить Path и Parameters, задав фильтр ID процесса + его имя.

Использую инструментарий WMIC.

Обновление v.1.1. (05.04.2013) - теперь путь к программе со спецсимволами (например, скобки) не должен вызывать падения скрипта.
("закавычил" переменные).
Развернуть код...
Bash
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@echo off
Setlocal
 
::Получить PID, Path, Parameters по имени процесса
set ProcName=calc.exe
Call :GetProcessInfo "" "%ProcName%" ProcPath ProcParam PID
 
::Получить Name, Path, Parameters по PID процесса
::set PID=5000
::Call :GetProcessInfo "%PID%" "" ProcPath ProcParam ProcName
 
::Получить Path, Parameters по имени процесса и его PID
::set ProcName=calc.exe
::set PID=5000
::Call :GetProcessInfo "%PID%" "%ProcName%" ProcPath ProcParam
 
Echo Process Name = %ProcName%
Echo PID = %PID%
Echo Path = %ProcPath%
Echo Parameters = %ProcParam%
Echo.
pause
goto :eof
 
 
:GetProcessInfo %1-Proccess_PID %2-Process_Name %3-var.Process_Path %4-var.Process_Parameters %5-var.Optional-PID_or_Name
Setlocal EnableDelayedExpansion
::Making Query
if "%~1" neq "" Set Query=ProcessID^^=%~1
if "%~2" neq "" Set Query=Name^^="%~2"
if "%~1" neq "" if "%~2" neq "" Set Query=^^(ProcessID^^=%~1 and name^^="%~2"^^)
if "%~1"=="" if "%~2"=="" Echo Wrong Query. Must be at least 1 parameter %%1 or %%2.& Exit /B 1
for /f "tokens=1* delims==" %%A in (
  'WMIC path win32_process WHERE %Query% GET "CommandLine"^,"ExecutablePath"^,"Caption"^,"Handle" /value^|findstr /BC:"CommandLine" /C:"ExecutablePath" /C:"Caption" /C:"Handle"') do (
  if "%%A"=="CommandLine" Set "ProcParse=%%B"
  if "%%A"=="ExecutablePath" Set "ProcessPath=%%~dpB"
  if "%%A"=="Caption" Set "ProcName=%%B"
  if "%%A"=="Handle" Set "PID=%%B"
)
::Parse Parameters
Set /A n=0& Set Param=
for %%A in (%ProcParse%) do Set /A n+=1& if !n! neq 1 (Set "Param=!Param!%%A ")
EndLocal& (
  if "%ProcessPath%" neq "" Set "%~3=%ProcessPath:~0,-1%"
  if "%Param%" neq "" Set "%~4=%Param:~0,-1%"
  if "%~5" neq "" if "%~1"=="" (set "%~5=%PID%") else (if "%~2"=="" set "%~5=%ProcName%")
)
Exit /B 0
3
Клюг
 Аватар для Charles Kludge
7677 / 3192 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
21.01.2013, 11:56
Цитата Сообщение от Dragokas Посмотреть сообщение
2) Команды "вывести на экран сумму 1 + 1"
Bash
1
2
Set /A n= 1 + 1
Echo %n%
разрывать нельзя, так как значение переменной "n" будет утеряно.
ORLY?
Bash
1
2
3
4
5
Set /A n= 1^
+ 1^
+2^
+3
Echo %n%
 Комментарий модератора 
Имелось в виду выполнять в разных сессиях интерпретатора
За фишку с птичками спасибо. Напомнил, тоже хорошая вещь, когда пишешь длинные запросы.
3
Клюг
 Аватар для Charles Kludge
7677 / 3192 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
22.01.2013, 20:24
Undocumented Dynamic variables (read only)

%__CD__% текущий каталог, с бэкслэшем'\' в хвосте;

%=C:% Текуший каталог на диске C:

%=D:% Текуший каталог на диске D:,E:,F:...(буковку подставите), если к нему было обращение в текущем сеансе CMD.EXE

%=ExitCode% Шестнадцатеричное значение кода возврата по EXIT /B

%=ExitCodeAscii% Символьное (ASCII) представление кода возврата по EXIT /B (допускается код в пределах от 32 до 126).
Windows Batch file
1
2
3
4
5
6
7
8
@echo off
echo %__CD__%
echo %=C:%
set "decimal=%1"
cmd /c exit /b  %decimal%
echo ASCII(как символ) exitcode: %=ExitCodeAscii%
echo Hex exitcode: %=ExitCode%
pause
7
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
22.01.2013, 22:41  [ТС]
Клас
Миниатюры
Тонкости языка, редкие команды и сложные скрипты  
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
23.01.2013, 02:24  [ТС]
Переключение языка команд консоли на английский

Тема: Английский язык в командной строке
0
Модератор
Эксперт JS
 Аватар для Eva Rosalene
5241 / 2115 / 416
Регистрация: 06.01.2013
Сообщений: 4,846
03.02.2013, 14:16
Экранировать восклицательный знак.
Если у вас в программе используется
Bash
1
setlocal enabledelayedexpansion
, то наверняка вставала проблема, как экранировать восклицательный знак, например, для вывода на экран. Стандартным способом он не экранируется, поскольку, скорее всего, раскрывается 2 раза.
Как экранировать:
Bash
1
^^^!
Итак, первый "^" экранирует второй "^", а третий "^" - экранирует сам восклицательный знак первый раз. Во второй раз остаются только "^"(второй) и "!", после чего "!" экранируется.
Bash
1
2
3
4
5
@echo off
setlocal enabledelayedexpansion
echo ^^^!
pause>nul
exit /b
А в кавычках он экранируется так:
Bash
1
set "$=^!"
Также его можно записать в переменную такой строкой:
Bash
1
(set $=^^^!)
и подставлять в нужном месте (даже в кавычках) как !$!
6
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
19.03.2013, 02:08  [ТС]
Деление через строковую математику
Отличие от встроенного в CMD деления: исходное число (делимое) может превышать границу для числового типа данных CMD
(актуально для Гигабайтов данных, представленных в виде байтов, для дальнейшего перевода в более удобо-читаемую единицу измерения).

Кликните здесь для просмотра всего текста
Bash
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@echo off
SetLocal EnableDelayedExpansion
::Делимое
set Num1=16261316608
::Делитель
Set Num2=1024
::Макс. кол-во знаков после запятой в результате
Set MaxZ=2
 
 
set /a Num1_pos=-1
 
:AddNum1
set /a Num1_pos+=1
::если строка закончилась
if "!Num1:~%Num1_pos%,1!"=="" Goto AfterZiro
Set Num1_part=%Num1_part%!Num1:~%Num1_pos%,1!
if %Num1_part%==00 Set Num1_part=0
Call :TryDiv
Goto AddNum1
 
:AfterZiro
if %Num1_part%==0 goto Div_End
if %MaxZ% neq 0 Set ResultAll=%ResultAll%.
Set Zero_Marker=true
 
:AddZiro
Set /A MaxZ-=1
if %MaxZ% LSS 0 Goto Div_End
echo %Num1_part%
if %Num1_part%==0 goto Div_End
Set Num1_part=%Num1_part%0
Call :TryDiv
Goto AddZiro
 
:Div_End
echo %ResultAll%
 
pause
Goto :eof
 
:TryDiv
Set /a Result=Num1_part / Num2
echo %Num1_part%-%result%
if %Result% neq 0 (
  Set ResultAll=%ResultAll%%Result%
  Set /A Num1_part=Num1_part - Result * Num2
) else (if "%ResultAll%" neq "" if not Defined Zero_Marker Set ResultAll=%ResultAll%0)
Exit /B


Пример довольно прямолинеен, и не оптимизирован. Зато работает верно, надеюсь Просьба - протестировать с разными числами.
Позже будет время - причешу.
4
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.03.2013, 02:08
Помогаю со студенческими работами здесь

Логические команды языка Ассемблер
Всем привет. Тема: Изучение группы логических команд. Задание: Дано состояние 24 двоичных позиционных датчиков, сигнализирующих...

Создать команды языка управления потоками
Создайте команды языка управления потоками для каждого из следующих случаев: а. Если средний status (статус) здания больше 1, то...

сложные зад4чи, парсинг, компиляторы, автоматическое преобразование исходника, сложные Regex
специализируюсь на работе со всякого рода парсингом и автоматическим форматированием/переписыванием. Имею опыт написания и использования...

Правило перевода на язык паскаль команды повторения с параметром алгоритмического языка?
Сформулируйте правило перевода на язык паскаль команды повторения с параметром алгоритмического языка?

Используя команды языка пакетного файла, реализовать текстовое меню из 4-х пунктов
Используя команды языка пакетного файла , реализовать текстовое меню из 4 пунктов , при выборе от 1 до 3 пункта ссылки на файлы и сделать...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
BOINC: 22 года — и всё ещё работает
Programma_Boinc 12.03.2026
BOINC: 22 года — и всё ещё работает Дэвид Андерсон написал ретроспективу. Кратко: в 2001 году он ушёл из United Devices, где был CTO, и за несколько месяцев написал ядро BOINC — клиент, сервер,. . .
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru