Статья Переменные в CMD, команда SET и арифметика. Файл переменные bat
Основы BAT файлов
В этой статье:
- Определение переменных
- Переменные командной строки (параметры вызова bat-файла)
- Оператор условия IF
- Функции
- Использование возвращаемых значений (обработка кода завершения программы)
Определение переменных
SET <Имяпеременной>=<Значениепеременной>
Оператор SET представляет собой расширение возможностей работы с параметрами в операционной системе. Он задает переменную, значение которой подставляется вместо ее имени при любом использовании этого имени между знаками процента. Так, если задано (переменная, которую требуют многие игры, использующие звуковую карту компьютера):
SET BLASTER=A220 I5 D1 P330
то при использовании в пакетном файле следующей конструкции:
ECHO %BLASTER%
на экран будет выведено "A220 I5 D1 P330". Переменные, определенные с помощью оператора SET называются переменными окружения среды (environment) и являются видимыми после выполнения до перезапуска DOS (если не изменять ее вручную в памяти). То есть, ее можно использовать из одного пакетного файла или программы после задания в другом. Наиболее известной является переменная PATH, представляющая собой набор путей для быстрого поиска файлов. Она задается в файле autoexec.bat.
Переменные командной строки(параметры вызова bat-файла)
%<цифра 0-9>
Как и в любом языке, в языке пакетных файлов возможно использование переменных, полученных в качестве параметров bat-файла.
Всего может быть 10 одновременно существующих независимых переменных. Для написания сложных программ это довольно мало, хотя для обычной работы часто хватает и 3-4. Значение переменной равно значению соответствующего параметра из командной строки. Переменная %0 будет содержать имя .bat-файла и, если вы указали, путь к нему. То есть, если вы запустили файл abc.bat со следующими параметрами:
abc.bat a bc def
то переменная %0 будет содержать значение abc.bat, %1 будет содержать значение a, %2 будет содержать bc, а %3 - def. Это свойство широко используется для создания универсальных пакетных файлов при работе с повторяющимися операциями.
Чтобы получить более чем 10 переменных из командной строки, можно воспользоваться командой SHIFT.
Команда SHIFT позволяет использовать число параметров командной строки далее 10. Однако, при этом теряются соответственно более ранние параметры. Иными словами, команда SHIFT сдвигает все значения переменных на один шаг влево. То есть, переменная %0 будет содержать значение, содержавшееся до этого в переменной %1, а переменная %1 - значение переменной %2 до сдвига. Однако, данная операция является необратимой, то есть, невозможно сдвинуть переменные обратно.
Оператор условия IF
К счастью, командный интерпретатор cmd.exe современных ОС Windows 2000 и старше поддерживает блоки команд в конструкциях ветвления, что устраняет необходимость применения IF с метками. Блоки команд заключаются в круглые скобки. Выглядит это так (имитируя C/C++ indentation style):
if condition (
rem Команды ветки ‘then’
rem ...
) else (
rem Команды ветки ‘else’
rem ...
)
Конкретный пример использования:
@echo off
set BUILDMODE=%1
if "%BUILDMODE%" == "" (
echo FAIL: Аргумент является обязательным ^(--debug, --release^)
exit /b 1
)
rem Удаляем из аргумента все дефисы для упрощения обработки
set BUILDMODE=%BUILDMODE:-=%
if "%BUILDMODE%" == "debug" (
echo INFO: Устанавливаем debug-режим окружения
set CCFLAGS=/Od /MDd /Z7
) else (
echo INFO: Устанавливаем release-режим окружения
set CCFLAGS=/O2 /MD
)
На мой взгляд, с этим уже вполне можно жить. Но, как всегда, жизнь не так проста, как кажется. Есть одна проблема. Переменные, использующиеся в блоках then и else, раскрываются перед началом выполнения этих блоков, а не в процессе выполнения. В приведенном примере это не вызывает никаких проблем, однако в следующем вызовет:
if "%BUILDMODE%" == "debug" (
echo INFO: Устанавливаем debug-режим окружения
set OPTFLAGS=/Od
set CCFLAGS=%OPTFLAGS% /MDd /Z7
) else (
echo INFO: Устанавливаем release-режим окружения
set OPTFLAGS=/O2
set CCFLAGS=%OPTFLAGS% /MD
)
Загвоздка в том, что в обоих блоках подстановка переменной OPTFLAGS произойдет до того, как она будет изменена в процессе выполнения этого блока. Соответственно, в CCFLAGS будет подставлено то значение, которое OPTFLAGS имела на момент начала выполнения данного if-блока.
Решается эта проблема путем использования отложенного раскрытия переменных. Переменные, заключенные в !…! вместо %…%, будут раскрыты в их значения только в момент непосредственного использования. Данный режим по умолчанию отключен. Включить его можно либо использованием ключа /V:ON при вызове cmd.exe, либо использованием команды:
setlocal enabledelayedexpansion
в тексте самого bat-файла. Второй способ мне представляется более удобным – не очень здорово требовать от кого-то запуска твоего сценария с определенным параметром.
С учетом сказанного предыдущий «неправильный» пример может быть исправлен так:
setlocal enabledelayedexpansion
if "%BUILDMODE%" == "debug" (
echo INFO: Setting up debug mode environment
set OPTFLAGS=/Od
set CCFLAGS=!OPTFLAGS! /MDd /Z7
) else (
echo INFO: Setting up release mode environment
set OPTFLAGS=/O2
set CCFLAGS=!OPTFLAGS! /MD
)
Вот теперь это почти полноценный if-then-else блок. Почти, потому что если в одной из команд echo у вас встретится закрывающая круглая скобка, то вам необходимо заэкранировать ее символом ^, иначе синтаксический анализатор путается…
Но в любом случае, это гораздо лучше безумного количества меток и переходов.
Функции
А можно создать в bat-файле функцию? Да, можно. Более того, иногда даже нужно. Правда, функциями это можно назвать условно.
Есть особый синтаксис команды call, который позволяет перейти на метку в этом же bat-файле с запоминанием места, откуда был произведен этот вызов:
call :метка аргументы
Возврат из функции производится командой:
exit /b [опциональный код возврата]
Ключ /b здесь очень важен: без него будет произведен выход не из функции, а из сценария вообще.
За подробностями наберите в командной строке:
call /?
exit /?
Что интересно, команда call с таким синтаксисом поддерживает рекурсивные вызовы с автоматическим созданием нового фрейма для переменных аргументов %0-%9. Иногда это может быть полезным. Вот классический пример рекурсивного подсчета факториала на командном языке:
@echo off
call :factorial %1
echo %RESULT%
exit
rem Функция для подсчета значения факториала
rem Вход:
rem %1 Число, для которого необходимо подсчитать факториал
rem Выход:
rem %RESULT% Значение факториала
:factorial
if %1 == 0 (
set RESULT=1
exit /b
)
if %1 == 1 (
set RESULT=1
exit /b
)
set /a PARAM=%1 - 1
call :factorial %PARAM%
set /a RESULT=%1 * %RESULT%
exit /b
Пример работы:
> factorial.bat 10
3628800
Использование возвращаемых значений(обработка кода завершения программы)
Любая программа при завершении своей работы возвращает операционной системе код своего завершения. Принято при успешном завершении возвращать ноль, иначе - код ошибки. Иногда, или, вернее, часто, программа "сознательно" возвращает ненулевое значение для того, чтобы в пакетном файле можно было "узнать" некоторые подробности ее работы. Например, программа возвращает код нажатой клавиши, а .bat-файл по нему выполняет различные действия.
Каким же образом пакетный файл может узнать код завершения выполненной программы? Для этого предусмотрено ключевая переменная ERRORLEVEL.
Пример пакетного файла с errorlevel'ами:
@ECHO OFF
REM Запускаем программу prg1.exe
PRG1.EXE
REM Анализ кода завершения
IF ERRORLEVEL 2 GOTO FILENOTFOUND
IF ERRORLEVEL 1 GOTO WRITEERROR
IF ERRORLEVEL 0 GOTO EXITOK
GOTO ONEXIT
:FILENOTFOUND
ECHO Ошибка! Файл не найден!
GOTO ONEXIT
:WRITEERROR
ECHO Ошибка записи!
GOTO ONEXIT
:EXITOK
ECHO Программа завершена благополучно.
GOTO ONEXIT
:ONEXIT
Обратите внимание - анализ кода завершения начинается не с нуля, а с максимально возможного значения. Дело в том, что подобная проверка означает: "если errorlevel больше или равен значению, то...". То есть, если мы будем проверять, начиная с нуля, любое значение будет истинным на первой же строке, что неверно.
Это самая распространенная ошибка в подобного рода программах.
webhamster.ru
Переменные среды в CMD, BAT-файле
Бывает так, что написанный Вами BAT-файл работает на одном компьютере, но не работает на другом. Ошибка часто заключается в том, что были использованы прямые пути к файлам. Например батник для копирования всех текстовых файлов находящихся в папке windows на диске C
xcopy C:\windows\*.txt
Такой батник будет работать на любом компьютере, только если операционная система установлена на диск С, если ОС расположена на другом диске D,F,K,J и т.д., необходимо использовать переменную %WINDIR%
Такой батник будет работать на любом компьютере — без разницы на какой диск установлена ОС
xcopy %WINDIR%\*.txt
Переменные среды — текстовые переменные операционной системы, хранящие данные о ряде настроек системы. Используются переменные среды при копировании, перемещении, переименовании, удалении, создании файлов и папок других действий в командной строке.
Список переменных среды ОС Windows Вы можете посмотреть введя в командной строке: set и нажав клавишу Enter Также можно вывести список переменных в текстовый файл с помощью батника
set > docent.txt
Bat-файл с таким кодом создаст текстовый файл docent.txt(здесь и далее имена подставляйте свои)и выведет список переменных среды ОС Windows в этот текстовый документ в том-же месте где и располагается запущенный батник.
Список переменных сред
%ALLUSERSPROFILE% размещение профиля «All Users»
%APPDATA% используемое по умолчанию размещение данных приложений
%CD% путь к текущей папке
%CMDCMDLINE% строка команд, с помощью которой был запущен данный экземпляр Cmd.exe
%CMDEXTVERSION% номер версии текущих расширений обработчика команд
%COMPUTERNAME% имя компьютера
%COMSPEC% путь к исполняемой командной оболочке
%DATE% текущие данные, использует тот же формат, что и команда date /t
%ERRORLEVEL% код ошибки последней использовавшейся команды
%HOMEDRIVE% имя диска локальной рабочей станции
%HOMEPATH% полный путь к основному каталогу пользователя
%HOMESHARE% сетевой путь к общему основному каталогу пользователя
%LOGONSEVER% имя контроллера домена, который проверял подлинность текущей сессии
%NUMBER_OF_PROCESSORS% количество процессоров, установленных на компьютере
%OS% имя операционной системы
%PATHEXT% список расширений файлов
%PROCESSOR_ARCHITECTURE% архитектура процессора. Значения: x86, IA64
%PROCESSOR_IDENTFIER% описание процессора
%PROCESSOR_LEVEL% номер модели процессора, установленного на компьютере
%PROCESSOR_REVISION% номер модификации процессора
%ProgramFiles% путь к Program Files
%PROMPT% параметры командной строки для текущего интерпретатора
%RANDOM% произвольное десятичное число от 0 до 32767
%SYSTEMDRIVE% имя диска, содержащего корневой каталог
%SYSTEMROOT% размещение системного каталога Windows
%TIME% текущее время
%USERDOMAIN% имя домена, содержащего список учетных записей пользователей
%USERNAME% имя пользователя, выполнившего вход в систему
%USERPROFILE% размещение профиля для текущего пользователя
%WINDIR% размещение каталога операционной системы
Если Вы хотите посмотреть чему равна переменная среды на Вашем компьютере в командной строке(окно CMD), не забывайте прописывать впереди переменной «echo»
echo — команда предназначенная для отображения строки текста
Например если Вы захотите узнать текущее время %TIME% и просто напишите %TIME% в CMD — то получите ошибку: «Синтаксическая ошибка в имени файла, имени папки или метке тома»
Если напишете echo %TIME% — то узнаете точное время
Батником вывести информацию в txt можно так
echo off
chcp 1251
echo сегодня %DATE% время %TIME% >> docent.txt
echo имя компьютера %COMPUTERNAME% >> docent.txt
echo имя юзера %USERNAME% >> docent.txt
echo где Винда %WINDIR% >> docent.txt
echo и т.д. и т.п >> docent.txt
Использование переменной при удалении файлов и папок с помощью Bat файла
Удаление папки Docent которая находится на диске С в WINDOWS
RD С:\WINDOWS\Docent /S/Q
То-же самое, но удаляем папку с помощью переменной %WINDIR%
RD %WINDIR%\Docent /S/Q
Использование переменной при перемещении файлов
Перемещение текстового файла docent.txt из папки WINDOWS на диске С в папку Program Files которая тоже на диске С
MOVE «C:\WINDOWS\docent.txt» «C:\Program Files»
То-же самое, но перемещаем с помощью переменных %WINDIR% и %ProgramFiles%
MOVE «%WINDIR%\docent.txt» «%ProgramFiles%»скопировано с: http://docent777.ru/publ/ot_docenta/pro_batniki/peremennye_sredy_v_cmd_bat_fajle/1-1-0-29источник: www.docent777.ru
iteron.ru
Переменные в CMD, команда SET и арифметика
Переменные. Команда SET
Задание переменныхВручную
Ввод с клавиатурыCMD/BATCH:
set /p x="BBeduTe cTpoky: " Типы переменныхТип строка
Ограничение 8184 символа. Тип числоОграничение от -2147483647 до 2147483647.Использование переменных
Вывод значения переменных
Существующие переменные%RANDOM% - раскрывается в случайное десятичное число между 0 и 32767.(от 0 до (2^17)-1)
CMD/BATCH:
set /a random10=%random%/3277 Выводит случайное число от 0 до 9. У меня это число по нелепой псевдослучайности цифру секунды%CD% - раскрывается в строку текущей директории.%DATE% - раскрывается в текущую дату, используя тот же формат команды DATE.%TIME% - раскрывается в текущую дату, используя формат команды TIME.%ERRORLEVEL% - раскрывается в текущее значение ERRORLEVEL. Уровень ошибки, 0 - это нет ошибки, 1 - это есть ошибка, а другие это номера ошибки.Чтобы получить полный список переменных и их значений введите команду SET
Операции со строковыми или численными переменными
Соединение 2-ух строковых переменных
CMD/BATCH:
set x=Gaz set y=Prom echo %x%%y% (GazProm) Вывод определенного(ых) символа(ов) из строкиСимволы номеруются начиная с 0!Вывод 1-ого символаВывод 3-х символов с конца строкиВывод всей строки кроме 2-ух первых символовВывод всей строки кроме 2-ух последних символовВывод 3-х символов начиная с 3Удаление подстроки из строкиCMD/BATCH:
set str=babywka echo %str:ba=% (bywka) Замена подстроки из строки на другую подстрокуCMD/BATCH:
set str=babywka echo %str:bab=xlop% (xlopywka) Удаление кавычек(") из строкиCMD/BATCH:
set str2="qwerty" echo %str2:"=% (qwert) В данном случае: если кавычки в начале и конце строки - можно юзатьCMD/BATCH:
echo %str2:~1,-1% (qwert) Существуют 2 способа использовать переменную в переменной, например: вывод n-ого символаПервый способ с call set
CMD/BATCH:
call set x=%%str:~%n%,1%% echo %x% Второй способ с for и setlocal enabledelayedexpansionCMD/BATCH:
setlocal enabledelayedexpansion for /l %%i in (%n%,1,%n%) do (set x=!str:~%%i,1!) echo %x% тут неважно что в for писать, главное писать в do С циклами мы разберемся в следующей статье. Но, пока уточню: если код второго способа юзать в пакетном файле (BATнике), то вместо %i юзаем %%i.Операции с числовыми переменными
Увеличивание на единицу
Увеличивание в 2 разааналогичноВозведение в квадратВозведение в кубДелениеДеление в CMD является целочисленным!(то есть делится до целого числа)CMD/BATCH:
set /a x=15 set /a y=4 set /a xy=%x%/%y% (3) СложениеCMD/BATCH:
set /a x=5 set /a y=-6 set /a xy=%x%+%y% (5+(-6)=5-6=-1) ВычитаниеCMD/BATCH:
set /a x=5 set /a y=-6 set /a xy=%x%-%y% (5-(-6)=5+6=11) Вычисление остаткаУнарные операторы(Не знаю, как они называются)дает результат(%y%) 1, если переменная(%x%) равна 0, и 0 (%y%) в любых других случаяхCMD/BATCH:
Например set /a x=5 set /a y="!"%x% (0) set /a x=0 set /a y="!"%x% (1) дает результат -1-%x% (%y%) НапримерCMD/BATCH:
set /a x=5 set /a y="~"%x% (-1-5=-(1+5)= -6) set /a x=-3 set /a y="~"%x% (-1-(-3)=-1+3=3-1= 2) Отрицаниедает результат 0-%x% (%y%) НапримерCMD/BATCH:
set /a x=5 set /a y="-"%x% (-5) set /a x=-3 set /a y="-"%x% (3) Двоичные операторыCMD/BATCH:
set x=3 (в двоичной системе счисления - 0011) set y=5 (в двоичной системе счисления - 0101) Побитовое И (AND)Побитовое И — это бинарная операция, действие которой эквивалентно применению логического И к каждой паре битов, которые стоят на одинаковых позициях в двоичных представлениях операндов.Другими словами, если оба соответствующих бита операндов равны 1, результирующий двоичный разряд равен 1; если же хотя бы один бит из пары равен 0, результирующий двоичный разряд равен 0.
CMD/BATCH:
set /a xy=%x%"&"%y% (1, в двоичной системе счисления - 0001) Побитовое ИЛИ (OR)Побитовое ИЛИ — это бинарная операция, действие которой эквивалентно применению логического ИЛИ к каждой паре битов, которые стоят на одинаковых позициях в двоичных представлениях операндов.Другими словами, если оба соответствующих бита операндов равны 0, двоичный разряд результата равен 0; если же хотя бы один бит из пары равен 1, двоичный разряд результата равен 1.
CMD/BATCH:
set /a xy=%x%"|"%y% (7, в двоичной системе счисления - 0111) Побитовое исключающее ИЛИ (XOR)Побитовое исключающее ИЛИ (или побитовое сложение по модулю два) — это бинарная операция, действие которой эквивалентно применению логического исключающего ИЛИ к каждой паре битов, которые стоят на
одинаковых позициях в двоичных представлениях операндов.Другими словами, если соответствующие биты операндов различны, то двоичный разряд результата равен 1; если же биты совпадают, то двоичный разряд результата равен 0.
CMD/BATCH:
set /a xy=%x%"^"%y% (6, в двоичной системе счисления - 0110) К битовым операциям также относят битовые сдвиги. При сдвиге значения битов копируются в соседние по направлению сдвига. Различают сдвиг влево (в направлении от младшего бита к старшему) и вправо (в направлении от старшего бита к младшему). При логическом сдвиге значение последнего бита по направлению сдвига теряется (копируясь в бит переноса), а первый приобретает нулевое значение.Двоичный арифметический сдвиг
Арифметический сдвиг аналогичен логическому, но значение слова считается знаковым числом, представленным в дополнительном коде.Так, при правом сдвиге старший бит сохраняет свое значение. Левый арифметический сдвиг идентичен логическому.
Вправо
CMD/BATCH:
set /a xy=%x%">>"1 (1, в двоичной системе счисления - 0011->0001) set /a xy2=%y%">>"1 (2, в двоичной системе счисления - 0101->0010) set /a n=13 (в двоичной системе счисления - 1101) set /a xn=%n%">>"2 (3, в двоичной системе счисления - 1101->0011) set /a my=-%y%">>"1 (-3, в двоичной системе счисления - 1011(-5)->1101(-3)) ВлевоCMD/BATCH:
set /a xy=%x%"<<"1 (6, в двоичной системе счисления - 0011->0110) set /a xy2=%y%"<<"1 (10, в двоичной системе счисления - 0101->1010) set /a xy3=%y%"<<"4 (80, в двоичной системе счисления - 0101->1010000) set /a my=-%y%"<<"1 (-10, в двоичной системе счисления - 1011(-5)->10110(-10)) Максимальный размер отдельной переменной среды составляет 8192 байта.(у меня выходило только 8184, наверное это вместе с названием...) Максимальный общий размер всех переменных среды, включая имена переменных и знак равенства, составляет 65 536 Кбайт.И я забыл, про 8-ричную и 16-ричную систему счисления в CMD
Системы счисления
Числовые значения рассматриваются как десятичные, если перед ними не стоит префикс 0x для шестнадцатеричных чисел, и 0 для восьмеричных чисел. Например, числа 0x12, и 022 обозначают десятичное число 18.
Обратите внимание на запись восьмеричных числе: 08 и 09 не являются допустимыми числами, так как в восьмеричной системе исчисления цифры 8 и 9 не используются.
Восьмеричная система счисления
CMD/BATCH:
set /a x=022 (Это 22 в восьмеричной системе счисления, и 18 в десятичной) Можно производить все операции, также как и с десятеричными числами. Но после задания значения переменной, значение хранится в десятичной системе счисления. Например, сложениеCMD/BATCH:
set /a xy=022+07 (Это 22+7=31 в восьмеричной системе счисления, и 31 в десятичной) Шестнадцатеричная система счисленияCMD/BATCH:
set /a x=0x3A (Это 3A в восьмеричной системе счисления, и 58 в десятичной) ВычитаниеCMD/BATCH:
set /a xy=0x3A-0x66 (Это 3A-66=-54 в восьмеричной системе счисления, и -44 в десятичной) Сохранение в переменной вывода программы К сожаление, передача вывода программ на вход команды set не работает:CMD/BATCH:
echo 1|set /p AA="" set AA Поэтому можно воспользоваться временным сохранением в файл:CMD/BATCH:
echo 1> 0.tmp set /p AA="" <0.tmp del 0.tmp echo %AA% Примеры использования Узнать динамически генерируемое имя архива WinRar:CMD/BATCH:
rar a -z%Comment% -p%p% "-ag yyyy-mm-dd[n]" %OutPath%\%arhivename%.%ext% @%FileList% >rar.log.tmp for /f "tokens=2*" %%I in ('find /i "Creating archive" ^<rar.log.tmp') do @echo %%J >rarfilename.tmp set /p rarfilename="" <rarfilename.tmp del rarfilename.tmp Узнать имя последнего изменённого файла в папке:CMD/BATCH:
dir /b /a-d /o-d *.* >%temp%\0.tmp set /p lastfile="" <%temp%\0.tmp del %temp%\0.tmp echo "%lastfile%" Комментарий от Dragokas : По сути эта команда считывает в переменную первую строку файла:safezone.cc
Путь до размещения bat. Список локальных и глобальных переменных CMD BAT исполняемых файлов windows
полный путь до запущенного bat-скрипта Echo %~dp0 можно использовать для перехода в среду самого bat @cd %~dp0
Локальные переменные среды
Если системные переменные окружения доступны всегда по всей системе, то локальные работают только в рамках конкретной учётной записи пользователя. Их количество может быть значительным, а состав отличаться даже для разных пользователей одного и того же ПК. Однако, есть ряд переменных, которые обычно присутствуют везде.
ALLUSERSPROFILE | Обычно: C:\All Users (до Windows XP) или C:\Program Data (Windows 7 и выше) | Хранит путь к папке с данными установленных программ. |
CD | Путь | Хранит путь к текущей активной директории, в которой исполняются команды. |
CLIENTNAME | Текст (если существует) | Если задана, хранит имя компьютера, заданное в настройках текущего пользователя. |
CMDCMDLINE | Текст | Выдаёт полную команду (с параметрами), которая была использована для последнего запуска Командной строки. |
LOGONSERVER | Текст | Хранит имя контроллера домена текущего пользователя. |
PROMPT | Обычно: $P$G | Выдаёт параметры командной строки для текущего интерпретатора. |
SESSIONNAME | Обычно: Console | Выдаёт название типа текущей сессии Командной строки. При запуске с локального ПК имеет значение "Console". При удалённом вызове – "RDP-Tcp#<номер сеанса>". |
USERDOMAIN | Текст | Хранит имя домена (компьютера), в котором работает пользователь. |
USERNAME | Текст | Хранит имя учётной записи активного пользователя. |
USERPROFILE | Обычно: C:\Users\%USERNAME% | Выдаёт путь до каталога с профилем пользователя. |
Бывает так, что написанный Вами BAT-файл работает на одном компьютере, но не работает на другом. Ошибка часто заключается в том, что были использованы прямые пути к файлам. Например батник для копирования всех текстовых файлов находящихся в папке windows на диске C
xcopy C:\windows\*.txt
Такой батник будет работать на любом компьютере, только если операционная система установлена на диск С, если ОС расположена на другом диске D,F,K,J и т.д., необходимо использовать переменную %WINDIR%
Такой батник будет работать на любом компьютере — без разницы на какой диск установлена ОС
xcopy %WINDIR%\*.txt
Переменные среды — текстовые переменные операционной системы, хранящие данные о ряде настроек системы. Используются переменные среды при копировании, перемещении, переименовании, удалении, создании файлов и папок других действий в командной строке.
Список переменных среды ОС Windows Вы можете посмотреть введя в командной строке: set и нажав клавишу Enter Также можно вывести список переменных в текстовый файл с помощью батника
set > docent.txt
Bat-файл с таким кодом создаст текстовый файл docent.txt(здесь и далее имена подставляйте свои)и выведет список переменных среды ОС Windows в этот текстовый документ в том-же месте где и располагается запущенный батник.
Список переменных сред
%ALLUSERSPROFILE% размещение профиля «All Users»
%APPDATA% используемое по умолчанию размещение данных приложений
%CD% путь к текущей папке
%CMDCMDLINE% строка команд, с помощью которой был запущен данный экземпляр Cmd.exe
%CMDEXTVERSION% номер версии текущих расширений обработчика команд
%COMPUTERNAME% имя компьютера
%COMSPEC% путь к исполняемой командной оболочке
%DATE% текущие данные, использует тот же формат, что и команда date /t
%ERRORLEVEL% код ошибки последней использовавшейся команды
%HOMEDRIVE% имя диска локальной рабочей станции
%HOMEPATH% полный путь к основному каталогу пользователя
%HOMESHARE% сетевой путь к общему основному каталогу пользователя
%LOGONSEVER% имя контроллера домена, который проверял подлинность текущей сессии
%NUMBER_OF_PROCESSORS% количество процессоров, установленных на компьютере
%OS% имя операционной системы
%PATHEXT% список расширений файлов
%PROCESSOR_ARCHITECTURE% архитектура процессора. Значения: x86, IA64
%PROCESSOR_IDENTFIER% описание процессора
%PROCESSOR_LEVEL% номер модели процессора, установленного на компьютере
%PROCESSOR_REVISION% номер модификации процессора
%ProgramFiles% путь к Program Files
%PROMPT% параметры командной строки для текущего интерпретатора
%RANDOM% произвольное десятичное число от 0 до 32767
%SYSTEMDRIVE% имя диска, содержащего корневой каталог
%SYSTEMROOT% размещение системного каталога Windows
%TIME% текущее время
%USERDOMAIN% имя домена, содержащего список учетных записей пользователей
%USERNAME% имя пользователя, выполнившего вход в систему
%USERPROFILE% размещение профиля для текущего пользователя
%WINDIR% размещение каталога операционной системы
Если Вы хотите посмотреть чему равна переменная среды на Вашем компьютере в командной строке(окно CMD), не забывайте прописывать впереди переменной «echo»
echo — команда предназначенная для отображения строки текста
Например если Вы захотите узнать текущее время %TIME% и просто напишите %TIME% в CMD — то получите ошибку: «Синтаксическая ошибка в имени файла, имени папки или метке тома»
Если напишете echo %TIME% — то узнаете точное время
Батником вывести информацию в txt можно так
echo off
chcp 1251
echo сегодня %DATE% время %TIME% >> docent.txt
echo имя компьютера %COMPUTERNAME% >> docent.txt
echo имя юзера %USERNAME% >> docent.txt
echo где Винда %WINDIR% >> docent.txt
echo и т.д. и т.п >> docent.txt
Использование переменной при удалении файлов и папок с помощью Bat файла
Удаление папки Docent которая находится на диске С в WINDOWS
RD С:\WINDOWS\Docent /S/Q
То-же самое, но удаляем папку с помощью переменной %WINDIR%
RD %WINDIR%\Docent /S/Q
Использование переменной при перемещении файлов
Перемещение текстового файла docent.txt из папки WINDOWS на диске С в папку Program Files которая тоже на диске С
MOVE «C:\WINDOWS\docent.txt» «C:\Program Files»
То-же самое, но перемещаем с помощью переменных %WINDIR% и %ProgramFiles%
MOVE «%WINDIR%\docent.txt» «%ProgramFiles%»скопировано с: http://docent777.ru/publ/ot_docenta/pro_batniki/peremennye_sredy_v_cmd_b...источник: www.docent777.ru
uc.org.ru
Практические приемы программирования в bat-файлах | windows
В статье рассматриваются примеры практического использования в bat-файлах команд for, echo, goto, определения функций, экранирования символов, определения каталога запуска и многое другое.
Мы все любим писать серьезные вещи на серьезных языках. Шаблоны, C++, Reflection, Perl и многое другое – вот то, что мы любим, то, чему посвящаем длинные сообщения в форумах, то, что снится нам по ночам.
Однако в нашей повседневной деятельности встречаются и вещи, которые не так интересны и интеллектуальны. Мы не очень любим говорить об этом, делаем вид, что Это – грязно, нечистоплотно и недостойно нашего внимания. Однако, приходит день, приходит час и перст Судьбы находит нас – нам надо написать еще один батничек… Иногда это запускалка для построения проекта, которая должна при ошибке компиляции скопировать логи на сетевой диск, иногда – запуск обновления исходных текстов из SVN. Иногда – что-нибудь еще.
К чему я это все? А к тому, что поговорим мы о полезных хитростях при написании файлов сценариев на встроенном командном языке Windows. К счастью, это занятие не является доминирующим в профессиональной деятельности автора, так что я не обязуюсь заполнить абсолютно все пробелы в данной области. Кроме того, рожденный ползать летать не может, и из cmd.exe, увы, не получится ни /usr/bin/perl, ни даже /bin/sh. Так что, все нижеприведенное – просто некоторые интересные факты из жизни файлов с расширением bat, на которые автор обратил внимание во время решения различных практических задач автоматизации.
Наш урок будет построен по сугубо практическому принципу, известному в народе как Cookbook. Иными словами, я не буду вдаваться в синтаксические и семантические дебри командного языка Windows, а лишь продемонстрирую его возможности (хотел написать «мощь», но все-таки передумал). Именно поэтому большинство следующих заголовков будет начинаться со слова «Как». Впрочем, для полноты по ходу развития событий будут даваться подробные комментарии, в том числе и по языковым конструкциям.
ПРЕДУПРЕЖДЕНИЕ Практически все описанные здесь рецепты подойдут только для Windows 2000 и старше. Bat-язык Windows 9x, к счастью, можно считать почившим, так что здесь он не рассматривается. Более того, диалекты cmd.exe операционных систем Windows 2000, Windows XP и Windows Server 2003 также немного различаются. Все приведенное ниже создано и проверено на компьютере под управлением операционной системы Windows XP. За подробной информацией по различиям в реализации той или иной команды обращайтесь к [1]. |
Как экранировать символ?
В командном языке Windows существует некоторый набор символов с высоким приоритетом, которые всегда трактуются как спецсимволы. К ним, в частности, относятся:
- Операторы перенаправления ввода-вывода <, >, >>.
- Оператор конвейера |.
- Операторы объединения команд ||, & и &&.
- Оператор разыменования переменной %…%.
В случае если символ, относящийся к одному из таких операторов, должен быть включен в вашу команду в его литеральном смысле, вас ждут определенные неожиданности. Например, при выполнении вот такой строки
echo The ratio should be up to 10%символ процента будет «съеден» интерпретатором, который решит, что это попытка вывода значения какой-то переменной. В случае со знаком процента решение довольно хорошо известно и состоит в удвоении этого символа:
echo The ratio should be up to 10%%после чего все заработает так, как надо. Однако в других случаях все менее очевидно. Рассмотрим командный сценарий, который генерирует незатейливый HTML-файл:
@echo off set OUTPUTFILE=%1 echo <html> >%OUTPUTFILE% echo <head> >>%OUTPUTFILE% echo <title>This is a greeting page</title> >>%OUTPUTFILE% echo </head> >>%OUTPUTFILE% echo <body> >>%OUTPUTFILE% echo Hello World! >>%OUTPUTFILE% echo </body> >>%OUTPUTFILE% echo </html> >>%OUTPUTFILE%К сожалению, при попытке запуска этого "чуда инженерного разума" нас постигнет неудача в виде сообщения об ошибке "was unexpected at this time".
Оно и понятно: командный интерпретатор не в силах разобраться, где его просят вывести на экран символ HTML-тега, а где перенаправить вывод. В нормальных языках программирования эта проблема обычно решается обрамлением строковых литералов кавычками. Отчасти это помогает и в bat-файлах. Но лишь отчасти. Выполнение строки
echo "<html>" >%OUTPUTFILE%приведет к тому, что в выходной файл будут записаны и сами кавычки. Это явно не совсем то, что требуется.
К счастью, есть один малоизвестный способ, позволяющий добиться требуемого результата. Символ ^ позволяет экранировать любой другой символ с безусловным приоритетом. Таким образом, вышеприведенный пример генерации HTML может быть успешно записан так:
@echo off set OUTPUTFILE=%1 echo ^<html^> >%OUTPUTFILE% echo ^<head^> >>%OUTPUTFILE% echo ^<title^>This is a greeting page^</title^> >>%OUTPUTFILE% echo ^</head^> >>%OUTPUTFILE% echo ^<body^> >>%OUTPUTFILE% echo Hello World! >>%OUTPUTFILE% echo ^</body^> >>%OUTPUTFILE% echo ^</html^> >>%OUTPUTFILE%Таким же способом можно экранировать любой другой специальный символ. Очевидно, можно экранировать и сам ^. Не очень эстетично, зато дешево и практично. Слово «надежно» я пропустил умышленно…
Как перенести длинную строку?
Совет по поводу экранирующего символа ^ имеет еще одно применение: перенос строк. Я (как и многие из вас, наверное) люблю, чтобы любой исходный текст, который я пишу, выглядел красиво – даже *.bat-файлы. Одним из обязательных условий красоты и удобочитаемости кода для меня является его ширина: все строки должны умещаться в 78 столбцов. Можно поспорить по поводу числа 78, но в одном я непреклонен – ограничение на ширину текста кода должно быть, иначе это не код, а макароны.
Так вот долгое время *.bat-файлы портили мне жизнь тем, что иногда приходилось писать длинную строку – например, вызов какой-нибудь другой программы с кучей опций, и я не знал, что с этим делать. Происходило это нечасто, но всегда было неприятно. Но, к счастью, моя жизнь изменилась с тех пор, как я открыл для себя Супер-Символ ^:
packagebin.exe --recursive-search=yes --files-mask=exe,dll,pdb,obj ^ --archive-type=zip --archive-level=max --deliver-method=ftp ^ --deliver-target=ftp://ftp.site.comПомните лишь, что чудо-символ должен быть последним в строке – скажите «Нет!» концевым пробелам.
Как определить имя каталога, в котором находится запущенный командный файл?
Иногда сценарию надо знать полный путь к себе самому и/или к каталогу, в котором он находится. Это может понадобиться по разным причинам. Например, он должен достать из системы контроля версий исходники в каталог/src рядом с собой. Или, запускаются тесты из каталога/tests, и перед их запуском надо добавить каталог/bin в переменную PATH.
Можно, конечно, рассчитывать на то, что командный файл был вызван из того же каталога, где он находится, и тогда в качестве вышеупомянутогоможно использовать переменную окружения %CD% - полный путь к текущему каталогу. Однако любые допущения в нашем деле недопустимы (хороший каламбур, однако!). Поэтому приведу более надежное решение.
Прежде всего, вспоминаем, что переменная %0 в bat-файле соответствует нулевому аргументу командной строки, т.е. имени самого файла. После этого читаем скудную документацию для команды call:
call /?и обнаруживаем, что при использовании нумерованных переменных %0-%9 можно использовать некоторые модификаторы:
%~1 - разворачивает %1, удаляя кавычки (") %~f1 - разворачивает %1 в полный квалифицированный путь %~d1 - разворачивает %1 в букву диска %~p1 - разворачивает %1 в путь %~n1 - разворачивает %1 в имя файла %~x1 - разворачивает %1 в расширение файла %~s1 - развернутый путь будет содержать только короткие имена %~a1 - разворачивает %1 в атрибуты файла %~t1 - разворачивает %1 в дату/время создания файла %~z1 - разворачивает %1 в размер файла %~$PATH:1 - Ищет в каталогах, перечисленных в переменной среды PATH, и разворачивает %1 в полное квалифицированное имя первого совпадения. Если имя переменной среды не определено, или если файл не найден, этот модификатор вернет пустую строку и, более того, модификаторы можно объединять для получения сложных результатов:
%~dp1 - разворачивает %1 в букву диска и путь %~nx1 - разворачивает %1 в имя файла с расширением %~dp$PATH:1 – ищет %1 в каталогах, перечисленных в переменной среды PATH, и разворачивает в букву диска и путь к первому найденному файлу. %~ftza1 - разворачивает %1 в строку, подобную DIRТаким образом, правильным будет использовать в качестве тега сочетание %~dp0, которое будет раскрыто в полный путь к каталогу, где находится сценарий. Например,
"%~dp0\packagebin.exe" --recursive-search=yes --files-mask=exe,dll,pdb,obj ^ --archive-type=zip --archive-level=max --deliver-method=ftp ^ --deliver-target=ftp://ftp.site.com --deliver-source="%~dp0\bin"Обратите внимание на использование кавычек – потенциально каталог может иметь в своем пути пробел. Кавычки избавят от проблем в этом случае.
ПРЕДУПРЕЖДЕНИЕ Опасайтесь бездумного применения команды cd %~dp0 без проверки результата выполнения. Теоретически, эта команда должна сменить текущий каталог на каталог, в котором расположен командный файл. Как правило, это работает. Однако возможны неожиданности. Однажды был написан простой командный сценарий, задача которого была просто удалить все каталоги рядом с собой. В «свою» директорию он переходил как раз через cd %~dp0. Все было проверено на локальной машине – работало замечательно. После этого сценарий был помещен на файл-сервер, где ему и полагалось быть. Я зашел с помощью Far в сетевой каталог, и для контрольной проверки решил запустить файл еще раз. Дальнейшее словно в тумане. cmd.exe правильно определил местонахождение bat-файла: \\servername\sharename\directory. Однако при попытке сделать туда cd, он сказал, что UNC-пути в качестве текущих каталогов не поддерживаются и лучше он сменит текущий каталог на C:\WINDOWS… Это было действительно мудрое решение… Часть сценария, отвечавшая за удаление всех каталогов, сработала отлично – хорошо, что я успел вовремя остановить это безумие. В тот день я узнал, что такое System Restore… |
Как получить короткое (8.3) имя файла?
«А зачем? – спросите вы – Ведь мы живем в мире Интернета, Web-сервисов и NTFS с длинными именами файлов». Это действительно так, но иногда встречаются программы, которые отчаянно сопротивляются прогрессу, и в частности, не любят имен файлов и полных путей с пробелами. Одной из таких программ, кстати, является утилита build.exe из Windows DDK… В таких ситуациях спасает использование короткого, «беспробельного» DOS-имени для файла.
ПРЕДУПРЕЖДЕНИЕ Доступ к файлу по короткому имени может быть не всегда возможен. На файловой системе NTFS создание коротких псевдонимов для файлов может быть отключено путем установки в единицу значения «NtfsDisable8dot3NameCreation» в ключе реестра «HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem». |
Итак, все же (в предположении, что надругательства над NTFS не было) – как? Внимательный читатель должен был заметить в предыдущем разделе, что при обращении к переменным %0 - %9 можно использовать префикс (расширенный путь будет содержать только короткие имена)
%~s1который нам как раз мог бы помочь. Но есть засада – все эти полезные префиксы нельзя использовать с произвольной переменной окружения, а присваивание переменным %0 - %9 не поддерживается. К счастью, описываемые префиксы можно еще использовать с переменными цикла for, и это дает нам способ достичь требуемого результата. Например, вот так можно получить 8.3-путь к “Program Files”:
for /d %%i in ("%PROGRAMFILES%") do ( set PROGRAMFILESSHORT=%%~si ) echo 8.3-имя для каталога "%PROGRAMFILES%" -^> "%PROGRAMFILESSHORT%"Этот и другие модификаторы можно использовать и с любой другой формой цикла for, подробнее о которых можно узнать из (см. также статью [1]):
for /?Как перенаправить стандартный вывод в файл?
Плоха та короткая программа, которая не стремится стать большой. К сожалению, это правило применимо и к командным файлам Windows тоже – иногда bat-файлы вырастают до довольно больших размеров. Если при этом результат выполняемых команд должен журналироваться, то все становится совсем плохо – почти каждая строка имеет хвостик типа
echo Cleaning up the target directory >>%LOGFILE% ... echo The target directory has been cleaned >>%LOGFILE%Гораздо проще было бы перенаправить стандартный вывод в файл, чтобы все команды echo и вообще, все, что выводится на экран, автоматически попадали в журнальный файл. Сделать это можно следующим образом (рассмотрим на знакомом примере генерации HTML-файла):
@echo off set OUTPUT=out.html if "%STDOUT_REDIRECTED%" == "" ( set STDOUT_REDIRECTED=yes cmd.exe /c %0 %* >%OUTPUT% exit /b %ERRORLEVEL% ) echo ^<html^> echo ^<head^> echo ^<title^>This is a greeting page^</title^> echo ^</head^> echo ^<body^> echo Hello World! echo ^</body^> echo ^</html^>Здесь делается то же, что и раньше, но с перенаправлением стандартного вывода в файл out.html. Делается это простым способом – перезапуском сценарием самого себя. Сначала проверяется, не установлена ли переменная окружения STDOUT_REDIRECTED. Если она установлена, значит, сценарий уже перезапущен с перенаправленным выводом и можно просто продолжить работу. Если же переменная не установлена, то мы ее устанавливаем и перезапускаем скрипт (cmd.exe /c %0) с таким же набором параметров, что и исходная команда (%*) и перенаправленным в файл стандартным выводом (>%OUTPUT%). После завершения выполнения «перенаправленной» команды выходим.
Такое «единовременное» перенаправление имеет и еще один неочевидный плюс: файл открывается и закрывается только один раз, и всем командам и дочерним процессам передается дескриптор уже открытого файла. Во-первых, это чуть-чуть улучшит производительность (жизнь удалась – сроду бы не подумал, что буду когда-нибудь писать о производительности в bat-файлах). Во-вторых, это поможет избежать проблемы с невозможностью открыть файл для записи. Такое может случиться, если после выполнения одной из команд останется «висеть» какой-нибудь процесс. Он будет держать дескриптор интересующего нас файла и перенаправление вывода в этот файл для всех последующих команд провалится. Проблема может показаться надуманной, но однажды она украла у меня 2 часа жизни…
Как сложить два числа?
Краткий ответ – смотри:
set /?Длинный ответ таков. В bat-файлах можно производить довольно-таки продвинутые вычисления – продвинутые не в сравнении с другими языками, а в сравнении с отсутствием возможности что-либо вычислить вообще. Вычисление осуществляется командой set, если она выполняется с ключом /a. Поддерживается практически полный набор операторов языка C, включая шестнадцатеричный модификатор 0x. Переменные окружения в выражении не обязательно заключать в знаки процента – все, что не является числом, считается переменной. Подробнее – все-таки в man set, тьфу, то есть в set /?. А здесь напоследок – просто несколько примеров.
@echo off set ARG=1 rem Переменные окружения в выражении не обязательно заключать в %...% set /a RESULT=ARG + 2 echo %RESULT% rem Если выражение содержит какие-либо из символов non grata, надо rem заключить его в кавычки set /a RESULT="ARG << 2" echo %RESULT% rem Шестнадцатеричная арифметика set /a RESULT=0x1234 + 0x6786 echo %RESULT% rem И многое-многое другое...А можно создать в bat-файле функцию?
Да, можно. Более того, иногда даже нужно. Правда, функциями это можно назвать условно. Есть особый синтаксис команды call, который позволяет перейти на метку в этом же bat-файле с запоминанием места, откуда был произведен этот вызов:
call :метка аргументыВозврат из функции производится командой:
exit /b [опциональный код возврата]Ключ /b здесь очень важен: без него будет произведен выход не из функции, а из сценария вообще. За подробностями обращайтесь к:
call /?exit /?Что интересно, команда call с таким синтаксисом поддерживает рекурсивные вызовы с автоматическим созданием нового фрейма для переменных аргументов %0-%9. Иногда это может быть полезным. Вот классический пример рекурсивного подсчета факториала на командном языке:
@echo off call :factorial %1 echo %RESULT% exit rem Функция для подсчета значения факториала rem Вход: %1 Число, для которого необходимо подсчитать факториал rem Выход: %RESULT% Значение факториала :factorial if %1 == 0 ( set RESULT=1 exit /b ) if %1 == 1 ( set RESULT=1 exit /b ) set /a PARAM=%1 - 1 call :factorial %PARAM% set /a RESULT=%1 * %RESULT% exit /bПример работы:
> factorial.bat 10 3628800Как можно избежать использования goto?
Любой хоть сколько-то осмысленный *.bat-файл длиной больше 50 строк является ярким лозунгом в поддержку работы Дейкстры [3]. Мешанина из переходов вперед и назад действительно является кодом «только для записи». Можно ли что-то предпринять по этому поводу?
На самом деле можно. Как правило, большинство меток и переходов используются для организации ветвлений при проверке условий, т.е. банальных if-then-else блоков. В оригинале, bat-язык поддерживал только одну команду в блоке then, что автоматически приводило к идиомам вида:
if condition goto :THEN rem Команды ветки ‘else’ rem ... goto IF_END :THEN rem Команды ветки ‘then’ rem ... :IF_ENDНо к счастью, командный интерпретатор cmd.exe современных ОС Windows 2000 и старше поддерживает блоки команд в конструкциях ветвления, что устраняет необходимость применения меток. Блоки команд заключаются в круглые скобки. Выглядит это так (имитируя C/C++ indentation style):
if condition ( rem Команды ветки ‘then’ rem ... ) else ( rem Команды ветки ‘else’ rem ... )Конкретный пример использования:
@echo off set BUILDMODE=%1 if "%BUILDMODE%" == "" ( echo FAIL: Аргумент является обязательным ^(--debug, --release^) exit /b 1 ) rem Удаляем из аргумента все дефисы для упрощения обработки set BUILDMODE=%BUILDMODE:-=% if "%BUILDMODE%" == "debug" ( echo INFO: Устанавливаем debug-режим окружения set CCFLAGS=/Od /MDd /Z7 ) else ( echo INFO: Устанавливаем release-режим окружения set CCFLAGS=/O2 /MD )На мой взгляд, с этим уже вполне можно жить. Но, как всегда, жизнь не так проста, как кажется. Есть одна проблема. Переменные, использующиеся в блоках then и else, раскрываются перед началом выполнения этих блоков, а не в процессе выполнения. В приведенном примере это не вызывает никаких проблем, однако в следующем вызовет:
if "%BUILDMODE%" == "debug" ( echo INFO: Устанавливаем debug-режим окружения set OPTFLAGS=/Od set CCFLAGS=%OPTFLAGS% /MDd /Z7 ) else ( echo INFO: Устанавливаем release-режим окружения set OPTFLAGS=/O2 set CCFLAGS=%OPTFLAGS% /MD )Загвоздка в том, что в обоих блоках подстановка переменной OPTFLAGS произойдет до того, как она будет изменена в процессе выполнения этого блока. Соответственно, в CCFLAGS будет подставлено то значение, которое OPTFLAGS имела на момент начала выполнения данного if-блока.
Решается эта проблема путем использования отложенного раскрытия переменных. Переменные, заключенные в !…! вместо %…%, будут раскрыты в их значения только в момент непосредственного использования. Данный режим по умолчанию отключен. Включить его можно либо использованием ключа /V:ON при вызове cmd.exe, либо использованием команды
setlocal enabledelayedexpansionв тексте самого bat-файла. Второй способ мне представляется более удобным – не очень здорово требовать от кого-то запуска твоего сценария с определенным параметром.
С учетом сказанного предыдущий «неправильный» пример может быть исправлен так:
if "%BUILDMODE%" == "debug" ( echo INFO: Setting up debug mode environment set OPTFLAGS=/Od set CCFLAGS=!OPTFLAGS! /MDd /Z7 ) else ( echo INFO: Setting up release mode environment set OPTFLAGS=/O2 set CCFLAGS=!OPTFLAGS! /MD )Вот теперь это почти полноценный if-then-else блок. Почти, потому что если в одной из команд echo у вас встретится закрывающая круглая скобка, то вам необходимо заэкранировать ее символом ^, иначе синтаксический анализатор путается…
Но в любом случае, это гораздо лучше безумного количества меток и переходов.
Как обработать текстовый файл?
Иногда в командном файле необходимо получить доступ к содержимому некоторого текстового файла и некоторым образом это содержимое обработать. Например, прочитать файл настроек программы.
Для привнесения еще большей конкретики в процесс изучения зададимся целью прочитать файл с настройками следующего содержания:
buildmode=releasecompiler=cl.exearch=x86Ничего сверхъестественного – простой key=value формат с возможностью вставки Unix-style комментариев. Помочь в чтении и обработке этого файла нам сможет команда for. Ее дополнительные опции позволяют задать и разделители, и символ начала комментария, и кое-что еще. Вот командный файл, который выполняет поставленную задачу:
@echo off rem Читаем настройки из файла settings.txt, который должен располагаться в rem том же каталоге, что и bat-файл. Если не удалось распарсить настройки - rem выходим с ненулевым кодом возврата. call :read_settings %~dp0\settings.txt || exit /b 1 rem Прочитанные настройки: echo Build mode : %BUILDMODE% echo Compiler : %COMPILER% echo Architecture: %ARCH% rem Выход из сценария. Дальше - только функции. exit /b 0 rem Функция для чтения настроек из файла. rem Вход: %1 - Имя файла с настройками :read_settings set SETTINGSFILE=%1 rem Проверка существования файла if not exist %SETTINGSFILE% ( echo FAIL: Файл с настройками отсутствует exit /b 1 ) rem Обработка файла c настройками rem Здесь: eol=# указывает на то, что содержимое строки начиная с символа # rem и до ее конца может быть пропущено как комментарий. rem delims== указывает, что разделителем значений является символ = rem tokens=1,2 приводит к тому, что в переменную %%i будет занесен первый rem токен, а в %%j - второй. for /f "eol=# delims== tokens=1,2" %%i in (%SETTINGSFILE%) do ( rem В переменной i - ключ rem В переменной j - значение rem Мы транслируем это в переменные окружения set %%i=%%j ) exit /b 0Обильные комментарии должны помочь легко разобраться, что к чему. За подробностями, как обычно, отошлю к:
for /?Кстати, возможности команды for не ограничиваются чтением из файла. Возможно также чтение вывода другой команды. Например, так:
@echo off for /f "tokens=* usebackq" %%i in (`cmd.exe /c ver`) do ( set VERSION=%%i ) echo %VERSION%Особенно меня умиляет наличие опции “usebackq”, которая делает синтаксис отдаленно похожим на юниксовый. И в стенах царства Билла есть граждане, скучающие по /bin/sh и пытающиеся хоть как-то скрасить существование свое и окружающих. Следующий совет это также косвенно подтверждает.
Что это за упомянутые ранее операторы объединения команд?
Это операторы &, && и ||. Они практически совсем не освещены в документации, но полезны в повседневности. Они позволяют объединять несколько команд в одну, т.е. примерно так:
command1 & command2 command1 && command2 command1 || command2Форма этих операторов весьма соответствует их содержанию. В случае, пожалуй, наименее полезного оператора & вторая команда будет просто выполнена после первой, т.е. это равносильно простой записи:
command1 command2Оператор && гарантирует, что вторая команда будет выполнена только, если первая была выполнена успешно, т.е. с нулевым кодом возврата (он же %errorlevel%). Такие конструкции очень популярны в мире shell-сценариев Unix. Например:
cd sources && make cleanЯ был приятно удивлен, узнав, что cmd.exe тоже умеет выполнять такие конструкции. Это безопаснее и правильнее, нежели простое последовательное выполнение этих команд, и короче и проще, чем строгая проверка и обработка кодов возврата. Очень удобно при написании на скорую руку. Не менее полезен иногда и оператор ||. Суть его тоже логична – выполнить вторую команду, если первая дала сбой. Часто встречается в таких идиомах:
cd sources || exit 1Если перейти в каталог sources не удастся, то будет произведен выход с кодом ошибки 1. Если же первая команда отработает нормально, то вторая выполнена не будет. Например, такая простейшая защита помогла бы в случае с cd по UNC-адресу, описанному ранее.
Можно ли написать на bat-языке серьезную программу?
Пожалуй, нет. Серьезная программа должна все-таки выглядеть серьезно. А все написанное на командном языке Windows таковым назвать можно лишь с о-о-о-чень большой натяжкой. Так что для решения более сложных задач автоматизации лучше все-таки взять что-нибудь более функциональное:
- Perl
- Python
- Ruby
- JScript / VBScript
Последние, кстати, присутствуют в Windows 2000/XP по умолчанию (с некоторыми функциональными различиями) и в целом могут считаться заменой *.bat языку. Однако сдается мне, что *.bat-файлы проживут еще очень долго.
Как проверить, указан ли определенный аргумент в bat-файле?
Проверить наличие определенного параметра в bat-файле можно оператором if [%1]==[] goto, пример:
@echo off if [%1]==[] goto usage @echo Это не выполнится, если параметр %1 указан @echo Done.goto :eof :usage @echo Usage: %0 ^<EnvironmentName^> exit /B 1Как можно отменить (экранировать) действие специальных символов (< и >)?
Это можно сделать с помощью символа ^ (см. предыдущий пример).
Автор: Алексей Александров. Источник: RSDN Magazine #2-2005
[Ссылки]
1. Применение команды for в bat-файлах (technet.microsoft).2. DOS Command Index site:earthlink.net.3. О вреде оператора goto site:vspu.ac.ru.
microsin.net
Переменные среды в CMD, BAT-файле - Про .BATники(для чайников) - Статьи от Доцента - Полезные статьи
Переменные среды в CMD, BAT-файле
Бывает так, что написанный Вами BAT-файл работает на одном компьютере, но не работает на другом. Ошибка часто заключается в том, что были использованы прямые пути к файлам.
Например батник для копирования всех текстовых файлов находящихся в папке windows на диске C
xcopy C:\windows\*.txt
Такой батник будет работать на любом компьютере, только если операционная система установлена на диск С, если ОС расположена на другом диске D,F,K,J и т.д., необходимо использовать переменную %WINDIR%
Такой батник будет работать на любом компьютере - без разницы на какой диск установлена ОС
xcopy %WINDIR%\*.txt
Переменные среды — текстовые переменные операционной системы, хранящие данные о ряде настроек системы.
Используются переменные среды при копировании, перемещении, переименовании, удалении, создании файлов и папок других действий в командной строке.
Список переменных среды ОС Windows Вы можете посмотреть введя в командной строке: set и нажав клавишу Enter
Также можно вывести список переменных в текстовый файл с помощью батника
set > docent.txt
Bat-файл с таким кодом создаст текстовый файл docent.txt(здесь и далее имена подставляйте свои)и выведет список переменных среды ОС Windows в этот текстовый документ в том-же месте где и располагается запущенный батник.
Список переменных сред
%ALLUSERSPROFILE% размещение профиля «All Users»
%APPDATA% используемое по умолчанию размещение данных приложений
%CD% путь к текущей папке
%CMDCMDLINE% строка команд, с помощью которой был запущен данный экземпляр Cmd.exe
%CMDEXTVERSION% номер версии текущих расширений обработчика команд
%COMPUTERNAME% имя компьютера
%COMSPEC% путь к исполняемой командной оболочке
%DATE% текущие данные, использует тот же формат, что и команда date /t
%ERRORLEVEL% код ошибки последней использовавшейся команды
%HOMEDRIVE% имя диска локальной рабочей станции
%HOMEPATH% полный путь к основному каталогу пользователя
%HOMESHARE% сетевой путь к общему основному каталогу пользователя
%LOGONSEVER% имя контроллера домена, который проверял подлинность текущей сессии
%NUMBER_OF_PROCESSORS% количество процессоров, установленных на компьютере
%OS% имя операционной системы
%PATHEXT% список расширений файлов
%PROCESSOR_ARCHITECTURE% архитектура процессора. Значения: x86, IA64
%PROCESSOR_IDENTFIER% описание процессора
%PROCESSOR_LEVEL% номер модели процессора, установленного на компьютере
%PROCESSOR_REVISION% номер модификации процессора
%ProgramFiles% путь к Program Files
%PROMPT% параметры командной строки для текущего интерпретатора
%RANDOM% произвольное десятичное число от 0 до 32767
%SYSTEMDRIVE% имя диска, содержащего корневой каталог
%SYSTEMROOT% размещение системного каталога Windows
%TIME% текущее время
%USERDOMAIN% имя домена, содержащего список учетных записей пользователей
%USERNAME% имя пользователя, выполнившего вход в систему
%USERPROFILE% размещение профиля для текущего пользователя
%WINDIR% размещение каталога операционной системы
Если Вы хотите посмотреть чему равна переменная среды на Вашем компьютере в командной строке(окно CMD), не забывайте прописывать впереди переменной "echo"
echo — команда предназначенная для отображения строки текста
Например если Вы захотите узнать текущее время %TIME% и просто напишите %TIME% в CMD - то получите ошибку: "Синтаксическая ошибка в имени файла, имени папки или метке тома"
Если напишете echo %TIME% - то узнаете точное время
Батником вывести информацию в txt можно так
echo off
chcp 1251
echo сегодня %DATE% время %TIME% >> docent.txt
echo имя компьютера %COMPUTERNAME% >> docent.txt
echo имя юзера %USERNAME% >> docent.txt
echo где Винда %WINDIR% >> docent.txt
echo и т.д. и т.п >> docent.txt
Использование переменной при удалении файлов и папок с помощью Bat файла
Удаление папки Docent которая находится на диске С в WINDOWS
RD С:\WINDOWS\Docent /S/Q
То-же самое, но удаляем папку с помощью переменной %WINDIR%
RD %WINDIR%\Docent /S/Q
Использование переменной при перемещении файлов
Перемещение текстового файла docent.txt из папки WINDOWS на диске С в папку Program Files которая тоже на диске С
MOVE "C:\WINDOWS\docent.txt" "C:\Program Files"
То-же самое, но перемещаем с помощью переменных %WINDIR% и %ProgramFiles%
MOVE "%WINDIR%\docent.txt" "%ProgramFiles%"
docent777.ucoz.ru
bat файл и использование значения переменной %%
Вопрос: Необходимо заменять известную часть файла на значение переменной
Имеется файл users.txt, в нем на каждой строчке указан только номер телефона (11 символов на каждой строке). Я создаю цикл и при каждом проходе цикла: 1. меняется значение переменной %%a, которое равно значению строчки из файла users.txt 2. создается каталог с именем равным значению переменной %%a 3. копируется в созданный каталог известный мне файл (при копировании переименовывается имя, добавляет префикс равный значению %%a). Ниже привожу используемый мною код:Код Windows Batch file | ||
|
Код Windows Batch file | ||
|
forundex.ru