Что такое сценарий windows cmd

Совершенствуйте свои сценарии Сценарии для командной строки — это файлы с простым текстом, которые интерпретируются командным процессором как наборы команд, подлежащие последовательному исполнению. История сценариев для командной строки началась на заре

Совершенствуйте свои сценарии

Сценарии для командной строки — это файлы с простым текстом, которые интерпретируются командным процессором как наборы команд, подлежащие последовательному исполнению. История сценариев для командной строки началась на заре 80-х — именно с этого времени и по сей день оболочка Command.com в MSDOS поддерживает исполнение сценариев посредством простых пакетных файлов. Выпущенный в 1993 году вместе с Windows NT другой командный процессор, Cmd.exe, также поддерживает язык макропрограммирования, подобный языку пакетных файлов Command.com. Несмотря на солидный возраст технологии, макропрограммирование в оболочке Cmd.exe все еще широко используется специалистами по ИT. Например, простой сценарий с командой For может превратить команду, которая сама по себе работает одновременно только с одним компьютером или пользователем в командной строке, в команду, которая пошагово проходит другой текстовый файл и исполняется для каждой строки в этом файле. Благодаря тому что сценарии для командной строки являются файлами с простым текстом, который представляет собой набор команд, их легко создавать и менять и они удобны для восприятия. Но простота макропрограммирования обманчива. Небрежно написанный сценарий для командного процессора может вызывать проблемы. Мне приходилось наблюдать, как сценарии для командного процессора при неправильных допущениях относительно вычислительной среды и операционной системы в лучшем случае работали некорректно, а в худшем — внезапно выполняли разрушительные действия на системах. Чтобы читатели могли избежать подобных проблем, я подготовил 10 советов для создания более надежных сценариев, которые могут работать во многих вычислительных средах.

1.

По возможности используйте переменные среды

Используя переменную в сценарии, мы заключаем имя переменной между знаками процента (%), а когда сценарий исполняется, знаки процента и текст между ними заменяется значением этой переменной. Применение переменных делает код сценария более универсальным, поэтому у него больше шансов успешно работать на разных компьютерах. Например, в сценарии для командного процессора не стоит жестко прописывать установочный каталог Windows. Вместо этого следует использовать переменную SystemRoot, которая всегда будет указывать на конкретный установочный каталог Windows. Так, команда

Echo %SystemRoot%

будет отображать содержимое SystemRoot (т. е. установочного каталога Windows). Я неоднократно видел сценарии, в которых для того, чтобы указать на установочный каталог Windows, использовали запись C:WINDOWS. Если Windows установлена не в C:WINDOWS (например, Windows 2000 и более ранние версии устанавливаются в WINNT), сценарий не будет работать корректно. Чтобы увидеть список переменных среды, следует ввести в командной строке команду Set. Некоторые переменные не появляются в списке, генерируемом командой Set, потому что они динамически генерируются Cmd.exe. В табл. 1 показан список этих переменных. Как и в случае с другими переменными среды, эти переменные заключаются в знаки процента. Например, следующая строка сценария будет отображать текущие время и дату:

Echo %DATE% %TIME%

2.

Не следует ожидать, что обычные пакетные файлы для Command.com будут так же хорошо работать в Cmd.exe

Те, кто привык писать пакетные файлы для платформ MS-DOS или Windows 9x/Me, должны иметь в виду, что в новейших версиях Windows некоторых команд не существует. Два самых распространенных примера — команды Choice и Deltree. Просмотрите свои старые пакетные файлы, чтобы убедиться, что они корректно работают в оболочке Cmd.exe. В табл. 2 приведено несколько возможных замен для Choice и Deltree. Большинство замен имеют синтаксис, отличный от синтаксиса команд, на место которых они предлагаются, поэтому придется соответствующим образом изменить сценарии.

3.

В оболочке Cmd.exe используйте расширение .cmd

Пакетным файлам Command.com необходимо расширение .bat. Оболочка Cmd.exe тоже может использовать расширение .bat, но в более мощном языке макропрограммирования Cmd.exe многие команды несовместимы с Command.com. Таким образом, .bat файл, написанный для Cmd.exe, может сбоить, если пользователь попытается исполнить его в Command.com (например, в Windows 98). Один из способов избежать этой проблемы состоит в использовании расширения .cmd для сценариев. Поскольку Command.com не распознает расширение .cmd, он просто не будет исполнять пакетный файл, если его имя оканчивается на .cmd.

4.

Убедитесь в том, что нужные исполняемые файлы доступны

Если ваш сценарий задействует программы, которые не являются частью стандартной установки операционной системы, необходимо позаботиться о том, чтобы все такие программы были доступны. Следует также задокументировать эти зависимости в сценариях. Я предлагаю для обеспечения доступности исполняемых файлов помещать их в один каталог со сценарием. Тогда для их запуска используется синтаксис

«% ~dp0exename» …

где exename — это имя исполняемого модуля, который требуется запустить. Синтаксис %~dp0 возвращает диск, путь и имя файла текущего сценария без кавычек. Заключение всей строки в кавычки гарантирует работоспособность сценария, даже если имя файла или каталога, в котором находится сценарий, содержат кавычки.

5.

Правильно используйте двойные кавычки

Похоже, двойные кавычки («) являются общим источником путаницы для тех, кто пишет сценарии. Двойные кавычки — это всего лишь способ идентифицировать содержащие пробелы аргументы командной строки. Например, правильная на первый взгляд командная строка

dir C:Program Files

на самом деле дает команде Dir два аргумента: C:Program и Files. Чтобы воплотить свое намерение передать команде один аргумент C:Program Files (включая пробел), мы должны заключить его в двойные кавычки:

dir «C:Program Files»

Символы кавычек не являются частью имени папки. Они сообщают команде Dir, что текст между ними является одним аргументом.

Сценарии для командного процессора также поддерживают параметры командной строки. Чтобы воспользоваться параметрами командной строки сценария, нужно задействовать запись %n (где n — число от 0 до 9). Эта запись называется заменяющим параметром (или просто параметром). Например, сценарий будет заменять параметр %1 первым аргументом командной строки, %2 — вторым аргументом и т. д. Помимо параметров от %1 до %9, %0 заменяется именем сценария, %* заменяется целой командной строкой сценария (исключая имя сценария). Я упоминаю здесь параметры командной строки потому, что, когда Cmd.exe заменяет параметры от %1 до %9 соответствующими аргументами командной строки, он оставляет двойные кавычки, если они есть в аргументе. Напрашивается очевидный вывод: параметр сценария всегда будет заключен в кавычки, если он содержит пробелы. На этом наблюдении основано несколько простых правил, аккуратно следуя которым можно практически полностью устранить проблемы кавычек.

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

If {%1}=={} Goto :HELP

Исключение из этого правила составляет случай, когда мы используем синтаксис %~n, чтобы удалить кавычки параметра (см. следующее правило).

  • Не помещайте кавычки внутрь переменной среды. Наличие пробелов в переменных среды допускается, и кавычки при этом не нужны. Если нужно скопировать параметр в переменную, используйте синтаксис %~n (где n — число от 1 до 9), который возвращает параметр без кавычек. Например, строка

    Set DATAFILE=% ~1
    будет копировать первый параметр сценария (без кавычек) в переменную DATAFILE. Исключение составляет случай, когда вы создаете текст в кавычках, который будет передан в другую команду.

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

    Set TARGET=% ~2
    Copy %1 «%TARGET%»

Первая из этих строк копирует второй аргумент сценария в переменную TARGET, удаляя кавычки. Вторая строка синтаксически верна, потому что параметр %1 уже заключен в кавычки, если он содержит пробелы, а переменная TARGET должна иметь кавычки, потому что она может содержать пробелы.

6.

Применяйте команды Setlocal и Endlocal

Команда Setlocal копирует все переменные среды, а команда Endlocal восстанавливает все переменные со значениями, которые они имели перед запуском сценария. Endlocal также удаляет любые переменные, созданные сценарием. Использование обеих команд делает сценарий более самостоятельным и гарантирует, что сценарий «убирает за собой мусор» путем восстановления переменных среды в их оригинальные значения и удаления переменных, созданных сценарием.

Также можно использовать команду Setlocal Enableextensions, чтобы точно знать, что расширения команд включены. Расширения команд — это усовершенствования для группы внутренних команд Cmd.exe (например, If, For, Call), которые предоставляют дополнительные возможности по сравнению с командами Command.com, имеющими такие же имена. Расширения команд включены по умолчанию, но в тех редких случаях, когда они отключены, команда Setlocal Enableextensions гарантирует включение расширений команд. Чтобы получить более подробную информацию о расширениях команд, следует ввести в командной строке Cmd /?.

7.

Используйте при необходимости символ Escape

Cmd.exe использует символ каретки (^) как признак отмены специального значения зарезервированных символов командной оболочки. Например, амперсанд (&) является разделителем команд — он позволяет поместить несколько команд в одной строке. Если вы намерены использовать амперсанд в обычном, литературном смысле, то должны «аннулировать» его специальное значение, поместив перед ним символ каретки ^. Так, в строке

Echo The ^& character is
the command separator

символ ^ вынуждает командный процессор отменить обычную интерпретацию следующего за ним символа. Специальными символами являются символы ( ) < > ^ & |. Нет необходимости использовать признак отмены, если эти символы встречаются внутри строки, заключенной в кавычки.

8.

Не используйте команду Exit без ключа /b

Без ключа /b команда Exit закрывает текущую командную оболочку. Если кто-то запускает Cmd.exe и исполняет сценарий, который содержит команду Exit, текущая сессия командного процессора резко закроется. Команда Exit /b закрывает текущий сценарий, не закрывая текущую сессию командного процессора. Чтобы больше узнать о команде Exit, наберите в командной строке Exit /?.

9.

Используйте команду If Errorlevel с осторожностью

Команда If Errorlevel проверяет код завершения последней команды, исполнение которой окончено. Поведение сценария зависит от результата проверки кода завершения программы. Рассмотрите, например, следующий сценарий:

Myprogram
If Errorlevel 1 Goto :ERROR

Команда Goto в этих строках будет выполнена, только если Myprogram.exe возвращает код завершения больше или равный 1. Другими словами, «If Errorlevel n» не означает «если последний код завершения программы в точности равен n»; на самом деле это условие означает «если последний код завершения программы не меньше n». Учитывая такое поведение, следует проверять код завершения программы в порядке убывания (от самого большого к самому маленькому). Чтобы проверить конкретное значение кода завершения программы, используйте динамическую переменную ERRORLEVEL вместо команды If Errorlevel. Нужно иметь в виду, что команда If Errorlevel отличается от переменной ERRORLEVEL, стоящей в списке в табл. 1. Команда If Errorlevel обратно совместима с командой If Errorlevel из Command.com; переменная ERRORLEVEL доступна только в Cmd.exe.

10.

Учитывайте особенности команды Start

Команда Start запускает программу или команду в окне новой консоли. Однако, если попытаться запустить программу из папки, которая содержит пробелы (или если имя программы содержит пробелы), поведение команды Start может не соответствовать вашим ожиданиям. Например, следующая команда:

Start «C:Program FilesMicrosoft
OfficeOffice11Winword.exe»

не запускает Microsoft Word вопреки ожиданию. Вместо этого команда Start откроет новую сессию Cmd.exe, заголовком окна консоли которой будет заключенная в кавычки строка. Такое поведение объясняется тем, что команда Start использует первую строку в кавычках в ее командной строке как заголовок окна консоли.

Чтобы обойти эту странность, используйте пару кавычек для указания пустого заголовка, затем вводите строку программы, которую хотите запустить. Корректная программа Start выглядит примерно так:

Start «» «C:Program FilesMicrosoft
OfficeOffice11Winword.exe»

Всего не предусмотришь

Сценарии командного процессора Cmd.exe применяются весьма широко. Освоив приведенные в этой статье рекомендации, вы сможете создавать более надежные сценарии и избегать распространенных проблем.


Дополнительные материалы по написанию сценариев в online-доступе на сайте Windows IT Pro/RE

OneNote — полнофункциональная система хранения сценариев
http://www.osp.ru/text/302/3546232.html

Рекурсивная загрузка Web-узла целиком
http://www.osp.ru/text/302/3207223/

Программный доступ к информации о дисковых квотах
http://www.osp.ru/text/302/3177796.html

Организация печати данных из сценариев
http://www.osp.ru/text/302/3177769.html

Как написать сценарий, выдающий заметные предупреждения
http://www.osp.ru/text/302/3137821.html

Получение списка членов вложенных групп
http://www.osp.ru/text/302/3137821.html

Самодельный инструмент для инвентаризации аппаратных средств
http://www.osp.ru/text/302/2876185.html

Перенос и активация учетных записей пользователей
http://www.osp.ru/text/302/2863575.html

Получение функциональности с использованием управляющих компонентов
http://www.osp.ru/text/302/2863520.html

Извлечение информации из Web-страницы
http://www.osp.ru/text/302/2740759.html

Системные утилиты одной строкой
http://www.osp.ru/text/302/2740725.html


Таблица 1. Таблица 2.

Общие сведения о командном процессоре Windows.
Использование переменных в командных файлах.
Передача параметров командному файлу.
Переходы и метки.
Примеры командных файлов:
    — Своя команда для создания новых файлов.
    — Присвоение съемному диску одной и той же буквы.
    — Создание архива, имя которого содержит дату и время.
    — Выполнение только в заданный интервал времени.
    — Пример создания архива каталога пользователя.
    — Изменение даты и времени для файлов и папок.
    — Выполнение команд по расписанию.
    — Запуск и остановка служб Windows в командной строке.
    — Выдача на экран значения ERRORLEVEL.
    — Диалог с пользователем.
    — Задержки в командных файлах.
    — Определение доступности IP-адреса.
    — Определение текущей версии Windows.
    — Поиск в локальной сети компьютеров с запущенным приложением.
    — Поиск компьютеров с запущенным приложением по списку на основе сетевого окружения.
    — Выключение компьютеров по списку, созданному на основе сетевого окружения.
    — Поиск в локальной сети включенных компьютеров.
    — Работа с дисками, файлами и каталогами.
    — Работа с графическими приложениями из командной строки.
    — Перекодировка текстовых файлов .
Часто встречающиеся ошибки при написании командных файлов.
Использование .bat и .cmd в сценариях регистрации пользователей.

Общие сведения о командном процессоре Windows.

    Командные файлы (скрипты, сценарии, батники) — это обычные текстовые файлы с расширением .bat или .cmd, строки которых представляют собой специальные команды командного процессора (интерпретатора команд ) и/или имена исполняемых файлов. Командный процессор – это специальная программа, являющаяся обязательным элементом почти любой операционной системы, главным назначением которого, является предоставление пользователю средства для выполнения определенных программ без их компиляции и создания исполняемых файлов. Для операционных систем DOS и Windows9X в качестве интерпретатора команд использовался командный процессор command.com, для всех остальных ОС семейства Windows ( NT/2k/XP/Vista/7/8 и старше) — cmd.exe. Несмотря на непрерывное совершенствование средств создания и выполнения сценариев с использованием объектно-ориентированных языков, обычная командная строка и простые командные файлы, по-прежнему остаются основным инструментом для выполнения рутинных действий, диагностики сетевых проблем, автоматизации процессов резервного копирования и т.п. При всех недостатках реализации командного процессора в Windows, достойной альтернативы ему нет, и очевидно в ближайшем будущем, не будет.

    Строки командных файлов могут содержать специфические команды самого
процессора команд (FOR, ECHO, REM и т.п.) или имена исполняемых модулей
(net.exe, regedit.exe, sc.exe) Командный процессор может быть запущен в интерактивном режиме через Пуск — Выполнить — CMD.EXE. В данном режиме, вы увидите окно консоли с приглашением к вводу команд. Возможный список большинства консольных команд можно получить введя:

HELP

Справочную информацию по конкретной команде можно получить, указав ее название в качестве параметра команды HELP:

HELP Имя команды

Если вы работаете в русифицированной версии Windows, то учтите, что в среде командного процессора символы национального алфавита используются в DOS-кодировке. Для переключения между кодовыми страницами Windows и DOS используется команда

CHCP номер страницы

CHCP 866 — использовать кодовую страницу 866 (DOS)

CHCP 1251 — использовать кодовую страницу 1251 (WINDOWS)

Для просмотра и редактирования командных файлов, содержащих символы русского алфавита нужно использовать редактор с поддержкой DOS-кодировки. Если вы используете стандартное приложение «Блокнот» (notepad.exe), то для правильного
отображения символов русского алфавита нужно выбрать шрифт Terminal, с
помощью меню Правка — Шрифт…

Внешний вид окна CMD.EXE (консоли Windows) можно изменить с помощью команды

COLOR

В качестве аргументов для команды используются 2 шестнадцатеричные цифры, задающие цвет фона и цвет символа.

COLOR F0 — черные символы на белом фоне.

COLOR 0E — светло-желтые символы на черном фоне.

HELP COLOR — подсказка для команды COLOR.

Работа с командным процессором предполагает использование двух устройств — устройства ввода (клавиатуры) и устройства вывода (дисплей). Однако, имеется возможность изменить стандартно используемые устройства ввода-вывода с помощью специальных символов — символов перенаправления

> — перенаправление вывода

< — перенаправление ввода

Для вывода справки не на экран а, например, в файл с именем help.txt, можно использовать следующую команду:

HELP > help.txt

При выполнении данной команды, в текущем каталоге будет создан файл с именем help.txt, содержимым которого будет результат вывода команды HELP. Если файл help.txt существовал на момент выполнения команды, его содержимое будет перезаписано. Для того, чтобы дописать данные в конец существующего файла, используют удвоение символа перенаправления вывода — «>>»

Пример:

HELP GOTO > myhelp.txt — в файл myhelp.txt будет выдана справка по использованию команду GOTO

HELP COLOR >> myhelp.txt — в конец файла myhelp.txt будет дописана справка по использованию команды COLOR

Простейший пример перенаправления ввода:

cmd.exe < commands.txt
— командный процессор не будет ожидать ввода команд с клавиатуры, а считает их из файла commands.txt

   При запуске командного процессора можно указать конкретную команду в качестве аргумента командной строки:

cmd.exe /C HELP FOR — выполнить команду HELP FOR и завершиться (ключ /C)

cmd.exe /K HELP FOR — выполнить команду HELP FOR и перейти в режим ожидания дальнейшего ввода команд (ключ /K)

Подробную справку по использованию cmd.exe можно получить, введя в качестве аргумента ключ /?

cmd.exe /?

Кроме символов перенаправления ввода-вывода в командной строке могут
использоваться символы объединения команд — && и ||

cmd.exe /C «HELP IF > nul» && Echo HELP Executed || Echo HELP Not Executed
— выполнить команду HELP IF и при успешном результате выполнить
команду Echo HELP Executed, а при неуспешном — Echo HELP Not Executed.
Команды, объединяемые для
выполнения с помощью конструкции && , не нужно заключать в
двойные кавычки. Выполнение строки

cmd.exe /C «HELP IF > nul» && Echo HELP Executed || Echo HELP Not Executed

завершится сообщением HELP Executed, а выполнение

cmd.exe /C «HELP uIF > nul» && Echo HELP Executed || Echo HELP Not Executed

где неверно задан аргумент команды HELP ( uIF ), завершится сообщением
HELP Not Executed

Файлы с расширением .bat или .cmd в среде Windows стандартно открываются
командным процессором аналогично примеру, где список команд считывается не с
устройства ввода, а из текстового файла.

Использование переменных в командных файлах.

   Существует такое понятие, как переменные окружения
(environments)
— это переменные, значения которых характеризуют среду,
в которой выполняются команда или пакетный файл. Иногда их называют
переменными среды. Принимаемые значения этих переменных формируются при
загрузке, регистрации пользователя в системе, старте или завершении
некоторых приложений, и, кроме того, могут быть заданы с помощью специальной
команды SET

SET переменная=строка

переменная — имя переменной среды.

строка — строка символов, присваиваемая указанной
переменной.

Например, командная строка

SET myname=Vasya

создает переменную myname, принимающую значение Vasya.

Значение, присвоенное какой-либо переменной, доступно для обработки в
командных
файлах, при использовании ее имени, заключенного в знаки
процента — % . Например
команда выдачи текста на дисплей ECHO в виде:

ECHO date — выведет на экран слово «date»,
а команда

ECHO %date% выведет на экран значение
переменной date — текущую дату в формате операционной системы.

С помощью команды SET обычно задается и модифицируется путь поиска
исполняемых программ
— переменная окружения PATH.

SET PATH=C:\Windows;C:\windows\system32

После выполнения данной команды, поиск исполняемых файлов будет выполняться в
каталоге C:\Windows, и, если результат неуспешен, в
C:\windows\system32

Допустим Вам необходимо выполнить программу myedit.exe, размещенную в
каталоге C:\NewProgs

Если в командной строке не задан полный путь, а только имя
исполняемого файла — myedit.exe

то сначала будет выполняться поиск файла myedit.exe в текущем каталоге, и если
он не будет найден — в каталогах, список которых задается значением переменной
PATH. Символ ; является разделителем элементов в списке путей поиска.
Если в приведенном примере, текущим каталогом не является
C:\NewProgs, и в остальных каталогах, заданных значением переменной
PATH. нет исполняемого файла myedit.exe, то запуск приложения myedit.exe
завершится ошибкой. Однако, если есть необходимость его запуска без указания полного
пути и при любом значении текущего каталога, можно модифицировать значение
переменной PATH

Команда

SET PATH=C:\NewProgs;%path%

изменит текущее значение PATH,
добавив каталог C:\NewProgs в начало списка.

   Выполнение команды SET без параметров позволяет получить текущие
значения переменных окружения:

NUMBER_OF_PROCESSORS=1 — количество процессоров

OS=Windows_NT- тип ОС

Path=C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Far — путь поиска исполняемых файлов.

PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH — расширения для исполняемых файлов.

PROCESSOR_ARCHITECTURE=x86 — архитектура процессора.

PROCESSOR_IDENTIFIER=x86 Family 6 Model 8 Stepping 1, AuthenticAMD — идентификатор процессора.

PROCESSOR_LEVEL=6 — уровень (номер модели) процессора.

PROCESSOR_REVISION=0801 — версия процессора.

ProgramFiles=C:\Program Files — путь к папке «Program Files»

PROMPT=$P$G — формат приглашения командной строки $P — путь для текущего каталога $G — знак «>».

SystemDrive=C: — буква системного диска.

SystemRoot=C:\WINDOWS — каталог ОС Windows.


Значение некоторых переменных по команде SET не выдаются. В основном, это переменные, принимаемые значения которых динамически изменяются:

%CD% — Принимает значение строки текущего каталога.

%DATE% — Принимает значение текущей даты.

%TIME% — Принимает значение текущего времени.

%RANDOM% — Принимает значение случайного десятичного числа в диапазоне 1 -32767.

%ERRORLEVEL% — Принимает текущее значение кода завершения задачи ERRORLEVEL

%CMDEXTVERSION% — Принимает значение версии командного процессора CMD.EXE для расширенной обработки команд.

%CMDCMDLINE% — Принимает значение строки, которая вызвала
командный процессор.

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

ECHO %переменная%

ECHO %CD% — отобразить имя текущего каталога

ECHO %TIME% — отобразить текущее время

ECHO %ERRORLEVEL%
отобразить результат выполнения предыдущей команды.

Значения, принимаемые переменными окружения, могут быть расширены с помощью
специального признака — символа » ~ «, что получить частичное
значение (расширение переменной), или изменить его заменой какой-либо части.
Примеры использования расширений переменных рассмотрены ниже.


В состав дополнительных средств Windows 2000/XP, и в комплект дистрибутива Windows 7 входит специальная утилита для формирования пользовательских и системных переменных окружения SetX, позволяющая записывать имена и значения переменных в реестр . Ссылка «Список команд CMD Windows» в конце статьи.

Передача параметров командному файлу.

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

BAT-файл параметр1 параметр2 …
параметрN

В самом командном файле первый параметр будет доступен как переменная %1,
второй — %2 и т.п. Путь и имя самого командного файла доступно как переменная %0.
Для примера создадим командный файл, задачей которого будет выдача на экран значений введенных при его запуске параметров командной строки. Для вывода
текста на экран используется команда ECHO текст ,
однако если «текст» заменить на %0, — то будет выдано имя командного файла, %1 — первый аргумент, заданный в строке запуска, %2 — второй и т.д.

Создаем, например, командный файл params.bat следующего содержания:


echo off
echo Это командный файл %0

echo Первый параметр=%1

echo Второй параметр=%2

echo Третий параметр = %3

и запускаем его на выполнение следующей командой:


params.bat FIRST second «two words»

после его выполнения вы поймете, как это работает, и что
параметры содержащие пробелы, нужно заключать в двойные кавычки.

В первой строке командного файла используется
команда «echo off» для того, чтобы обрабатываемые командным процессором
строки не выдавались на экран.

   Для проверки наличия каких-либо входных параметров, передаваемых
командному файлу, можно проверить, является ли значение переменной %1
пустым:


if «%1» EQU «» goto error

….

:error

Echo Должен быть задан хотя бы один входной параметр

exit

   В командных файлах большого размера трудно обойтись без справочной
информации в виде комментариев, для чего используется конструкция

REM пробел текст

Строки, начинающиеся с REM пробел, командным процессором игнорируются.

rem ECHO OFF выключает режим вывода содержания строк командного
файла на экран

REM будет выводиться только результат их выполнения.

ECHO OFF

echo Первый параметр=%1

echo Второй параметр=%2

echo Третий параметр = %3

Если к имени команды первым символом добавляется @,
то независимо от режима ECHO (ON или OFF), вывод обрабатываемой строки не
выполняется. Попробуйте в данном примере «ECHO OFF» заменить на «@ECHO OFF» —
результат говорит сам за себя. Строка, которая выключает режим вывода,
не будет выдаваться на экран. Вывод эха на экран устанавливается по
команде ECHO ON и, обычно, используется в целях диагностики.


rem ECHO ON включает режим вывода содержания строк командного
файла на экран

REM будет сама командная строка и результат ее выполнения,

REM но строки, начинающиеся символом @ выводиться не будут
ECHO ON

@echo Первый параметр=%1

@echo Второй параметр=%2

@echo Третий параметр = %3

Переходы и метки.

    В командных файлах можно использовать команды условного перехода,
меняющие логику их работы в зависимости от выполнения определенных условий.
Для иллюстрации приемов использования условных переходов создадим командный
файл, целью которого будет присвоение заранее определенной буквы для
съемных носителей, в качестве которых будут использоваться флэш-диски.
Условия таковы — есть 2 флэш-диска, один из которых должен быть виден в
проводнике как диск X: а второй — как диск Y: независимо от того, в какой
порт USB они подключены и какие буквы присвоены им операционной системой.
Будем считать, что реальные диски могут быть подключены как F: или G:
Опознавание дисков будем выполнять по наличию файла с определенным именем
(лучше такой файл сделать скрытым в корневом каталоге и назвать его как-нибудь
необычно):

Flashd1.let — на первом диске

Flashd2.let — на втором

Таким образом, задача командного файла заключается в том, чтобы проверить
наличие на сменных дисках F: и G: файлов Flashd1.let
или Flashd2.let и, в зависимости от того, какой из них присутствует,
присвоить диску букву X: или Y:

Для поиска файла на диске воспользуемся командой IF EXIST:

IF EXIST имя_файла команда

В качестве команды проще всего воспользоваться SUBST, сопоставляющей имя диска и каталог.

SUBST X: C:\ — — создать виртуальный диск
X:, содержимым которого будет корневой каталог диска C:

    Для решения задачи, создаем командный файл, например setletter.bat, следующего содержания:


@ECHO OFF

IF EXIST G:\flashd1.let SUBST X: G:\

IF EXIST F:\flashd1.let SUBST X: F:\

IF EXIST G:\flashd2.let SUBST Y: G:\

IF EXIST F:\flashd2.let SUBST Y: F:\

    После выполнения этого командного файла у вас появятся диски X: и Y:

Однако, если такой файл выполнить повторно,
команда SUBST выдаст сообщение об ошибке — ведь диски X: и Y:
уже существуют.

Поэтому, желательно обойти выполнение SUBST, если виртуальные диски
X: и Y: уже созданы, или удалять их, используя SUBST с параметром -d
перед подключением. Попробуйте изменить командный файл setletter.bat с
использованием команды перехода GOTO,
осуществляющей передачу управления строке пакетного файла на указанную
метку.

GOTO метка

В качестве метки используется строка символов, начинающаяся
с двоеточия. Сделаем изменения в нашем командном файле, чтобы не возникало
сообщений об ошибке:

@ECHO OFF

REM если не существует X: — то перейдем на метку SETX

IF NOT EXIST X:\ GOTO SETX

REM если существует X: — перейдем на проверку наличия Y:

GOTO TESTY

:SETX

IF EXIST G:\flashd1.let SUBST X: G:\

IF EXIST F:\flashd1.let SUBST X: F:\

:TESTY

REM если Y: существует — завершим командный файл.

IF EXIST Y:\ GOTO EXIT

IF EXIST G:\flashd2.let SUBST Y: G:\

IF EXIST F:\flashd2.let SUBST Y: F:\

REM выход из командного файла

:EXIT

Конечно, данный пример не может считаться образцом программирования, но
главная цель, в данном случае, это не написание оптимального командного
сценария, а пояснения принципов использования меток и переходов. Далее по
тексту, я старался, насколько это возможно, использовать именно такой
подход — главное не оптимальность кода командного файла, а его максимальная
простота для понимания.

При выполнении измененного таким образом командного файла, сообщение об
ошибке при выполнении SUBST исчезнет.

Одним из важнейших приемов при написании сложных командных файлов
является анализ успешности выполнения конкретной команды или программы.
Признаки ошибок при выполнении команд можно отслеживать, анализируя
специальную переменную ERRORLEVEL ,
значение которой формируется при выполнении большинства программ.
Обычно ERRORLEVEL равно нулю, если программа завершилась без ошибок и
единице — при возникновении ошибки. Могут быть и другие значения, если они
предусмотрены в выполняемой программе.

   В качестве команды в строке командного файла можно использовать также
командный файл. Причем, для передачи с возвратом обратно к точке выполнения
вызывающего командного файла используется
команда CALL. Попробуйте создать командный файл test.bat, следующего содержания:


@ECHO OFF

ECHO Вызов 1.bat

CALL 1.bat

ECHO Возврат.

В этом же каталоге, создайте второй файл под именем 1.bat, содержащий
команду


PAUSE
, приостанавливающую выполнение командного файла до
нажатия любой клавиши.

@ECHO OFF

pause

При выполнении командного файла test.bat будет выдано на экран
сообщение

Вызов 1.bat

и управление получит командный файл 1.bat с одной единственной командой
pause. После начатия клавиши на клавиатуре управление будет возвращено
вызвавшему командному файлу
на строку «ECHO Возврат.» и на экран будет выдано

Возврат.

Если же в файле test.bat убрать CALL, оставив «1.bat», то возврат
выполняться не будет.

Вызываемый командный файл может создавать переменные и присваивать им
определенные значения, которые будут доступны для обработки в вызывающем
файле. Попробуйте изменить файл test.bat на следующее содержимое:


@ECHO OFF

ECHO Вызов 1.bat

CALL 1.bat

ECHO Получено из файла %MYFILE% значение MYNUMBER=%MYNUMBER%.

а в файле 1.bat на следующее


@ECHO OFF

SET MYFILE=»Very good 1.bat»

SET MYNUMBER=99

Кстати, используя передачу управления командному файлу, можно организовать
его зацикливание. Попробуйте добавить в конец файла test.bat строку:


CALL test.bat

Выйти из зацикливания командного файла можно по нажатию комбинации
CTRL-Break.

Возможно использование команды CALL для вызова процедуры внутри
командного файла.
В этом случае в качестве аргумента используется не имя внешнего файла, а
метка:


call :proc1

….

:proc1

….

exit

….

Примеры командных файлов.

   Использование утилит командной строки и командных файлов нередко позволяют
решить многие проблемы связанные с повседневной эксплуатацией компьютерной
техники. Большинство системных администраторов и грамотных пользователей
продолжают ими пользоваться, несмотря на то, что в Windows проявилось новое,
более мощное и современное средство управления системой — WMI
(Windows Management Instrumentation). Очевидно, не в последнюю очередь, это
обусловлено простотой реализации и, тем не менее, — достаточной
эффективностью использования командных файлов. Ниже приведены простые
примеры с комментариями, которые демонстрируют некоторые возможности и
способы применения .cmd и .bat

Своя команда для создания новых файлов.

   В составе операционной системы Windows нет специальной команды для создания нового файла, но без нее можно легко обойтись несколькими способами:

Копирование с клавиатуры в файл

COPY CON myfile.txt

При выполнении этой команды данные с клавиатуры (стандартное устройство CON — консоль) будут заноситься в файл myfile.txt. Нажатие клавиши F6 или комбинации CTRL-Z завершит вывод.

Перенаправление вывода

ECHO 1 > myfile.txt

При выполнении этой команды будет создан файл myfile.txt, содержащий символ «1»

Комбинация перенаправления ввода и перенаправления вывода:

COPY CON > myfile.txt < xyz

При выполнении этой команды, как и в первом случае, используется копирование
с консоли в файл, но вместо ручного ввода данных с клавиатуры используется ввод с
несуществующего файла xyz. Система выдаст сообщение, о том, что такого
устройства или файла
не существует, но пустой файл myfile.txt будет успешно создан.

Еще проще использовать команду копирования из фиктивного устройства nul в файл. Использование устройства nul позволяет обойти стандартные операции ввода-вывода, которые для него реально не выполняются.

COPY NUL myfile.txt

   При работе в командной строке часто приходится создавать новые пустые
файлы, поэтому, стоит подготовить свой командный файл (например, с
именем nf.bat),

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

Содержимое файла:

@echo off

REM Создание пустого файла, имя которого задано в строке запуска

if «%1» EQU «» goto error

copy nul %1

goto exit

:error

ECHO ОШИБКА: Необходимо задать имя нового файла !

:exit

    Для простоты использования, поместите этот командный файл в системный каталог
(например, в C:\windows\system32) или любой другой, существующий в путях
поиска, задаваемых значением переменной PATH). Теперь, в командной строке, находясь в любом каталоге можно одной командой создавать пустые файлы.

Командная строка:

nf.bat myfile.txt — создать файл с именем myfile.txt в текущем каталоге.

nf.bat C:\myfile.txt — создать файл в корневом каталоге диска C:

nf.bat «%USERPROFILE%\myfile.txt» — создать файл в каталоге профиля текущего пользователя.

Расширение командного файла (.bat) можно не набирать и команда еще больше упрощается:

nf myfile.txt

В тексте командного файла присутствует проверка, задано ли имя
создаваемого файла в командной строке (if «%1%» EQU «» goto error), и если не
задано — выводится сообщение об ошибке и командный файл завершает
свою работу.

В качестве тренировки, попробуйте добавить в этот командный файл проверку
на существование файла с именем, указанным в командной строке.

Присвоение съемному диску одной и той же буквы.

    Задача заключается в том, чтобы съемный USB диск (флэш диск) был доступен
всегда под одной и той же буквой, независимо от того, на каком компьютере он
используется
и как он подключен. Для ее решения воспользуемся уже упоминаемой выше
командой SUBST, но реализуем присвоение новой буквы диску с
использованием подстановочного значения переменной %0, создаваемой
системой при каждом запуске командного файла.

Выберем для съемного диска желаемую букву, например — X.

Некоторые из переменных окружения, в том числе и переменная %0
принимающая значение пути и имени выполняющегося командного файла, позволяют
при определенной модификации с использованием специального признака —
символа » ~ « получить ее частичное значение (расширение переменной).
Например, не полный путь
файла, а только его имя, или каталог расположения, или букву диска, с
которого он был запущен или еще около десятка различных элементов, связанных
с подстановочными значениями переменной %0.

Имя диска, с которого
был запущен командный файл доступно как переменная %~d0.

Теперь создаем командный файл следующего содержания:

@echo off

subst X: %~d0\

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

Дополнительное представление о подстановочных значениях
переменной %0 можно получить из командного файла следующего
содержания:

@echo off

ECHO ОБРАБАТЫВАЕТСЯ ФАЙЛ — %0

ECHO Дата/время создания/изменения командного файла — %~t0

ECHO Путь командного файла — «%~f0»

ECHO Диск командного файла — %~d0

ECHO Каталог командного файла — «%~p0»

ECHO Имя командного файла — %~n0

ECHO Расширение командного файла — %~x0

ECHO Короткое имя и расширение — %~s0

ECHO Атрибуты командного файла — %~a0

ECHO Размер командного файла — %~z0

Создание архива, имя которого содержит дату и время.

    Решим следующую задачу — нужно создать архив файлов, находящихся в каталоге
C:\Program Files\FAR. Имя архивного файла должно состоять из текущего времени
(часы.минуты.секунды — ЧЧ.ММ.СС.rar), и помещен он должен в новый каталог, имя которого должно состоять из текущей даты
(день.месяц.год — ДД.ММ.ГГГГ). Для архивирования будем использовать архиватор RAR.
Формат запуска для создания архива:

RAR a -r < путь и имя архива > < Путь и имя архивируемых данных >

a — команда создания архива.

-r — ключ, определяющий архивирование подкаталогов (т.к. в исходной папке есть подкаталоги).

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

  • В командных файлах можно получить доступ к текущей дате и текущему времени — переменные %DATE% и %TIME%
  • В командных файлах можно создавать временные переменные с помощью команды SET.
  • Значение временных переменных может быть сформировано на основе %DATE% и %TIME% путем пропуска и (или) замещения их частей с помощью специальной конструкции с использованием символа ~ и числового значения, определяющего группу символов из данных текущего значения переменной.

    Данный пример, как и многие другие в этой статье, представляет собой не самую оптимальную, с точки зрения программирования конструкцию, и представлен в виде, максимально доступном для понимания. Набравшись опыта в написании командных файлов, вы можете переделать его, превратив, буквально в пару строк.

    Дата, получаемая из переменной %DATE% при стандартных настройках региональных установок Windows 2000
    выглядит следующим образом:

    Пн 21.01.2005 — День недели(2 символа)-Пробел(1 символ)-дата(10 символов) — всего 13 символов.

    В Windows XP/Vista/7 день недели отсутствует, что несколько упрощает структуру даты.
    Для создания нового каталога в командной строке используется команда

    MD имя каталога .

    Имя каталога нужно получить из текущей даты.
    Создаем в памяти временную переменную VDATE и присваиваем ей значение
    переменной окружения DATE, без первых 3-х символов (Пн и пробел) — 20.01.2005:

    set VDATE=%date:~3%

    В версиях Windows, где в значении принимаемом переменной DATE, отсутствует
    день недели (3 символа — «Пн «), значение VDATE получится не тем, что
    требуется. Чтобы не анализировать признаки наличия данного кода, можно
    воспользоваться и другим вариантом — не пропустить первые 3 символа (~3) от
    начала строки переменной DATE, а взять 10 символов от конца строки, указав число 10 со знаком «минус» — будет тот же результат — 20.01.2010

    set VDATE=%date:~-10%

    Создаем каталог на диске C:, имя которого = текущая дата из переменной VDATE:

    MD C:\%VDATE%

    После выполнения этой команды на диске C: будет создан каталог с именем 20.01.2005

    Можно обойтись без лишних операторов, связанных с формированием значения переменной VDATE, которую я использовал для упрощения понимания структуры создаваемого имени каталога:

    MD %DATE:~-10% — создать каталог, имя которого будет представлено в виде текущей даты ДД.ММ.ГГГГ

    Время, получаемое из переменной %TIME% выглядит так :

    14:30:59.93 — Часы, минуты, секунды, сотые доли секунды.

    Сотые доли — это в имени файла архива, пожалуй, лишнее. Создаем временную
    переменную VTIME и присваиваем ей текущее время без последних 3-х символов, т.е
    пропускаем 0 символов от начала и отсекаем 3 символа от конца. Количество пропущенных и отсекаемых символов разделяются запятой:

    set VTIME=%time:~0,-3%

    Теперь VTIME = 14:30:59, но знак двоеточия ( : ) в имени файла использовать нельзя, это специальный символ, использующийся в именах устройств (диск C:\). Поэтому, его придется заменить его на любой другой символ, допустимый в имени файла, например, точку. Для замены символов используется знак » = «

    set VTIME=%VTIME::=.% — заменить в переменной VTIME символ двоеточия на символ точки.

    Переменная VTIME примет значение 14.30.59

    Запустим архиватор:

    rar.exe a -r C:\%VDATE%\%VTIME%.rar «C:\Program files\far\*.*»

    Теперь можно создать командный файл с содержимым:

    set VDATE=%date:~-10%

    md c:\%VDATE%

    set VTIME=%time:~0,-3%

    set VTIME=%VTIME::=.%

    rar.exe a -r C:\%VDATE%\%VTIME%.rar «C:\Program files\far\*.*»

        Такой командный файл можно выполнять через автозагрузку, или как часть
    скрипта, при входе пользователя в домен, либо с помощью планировщика в
    заданное время, и у вас всегда будут в наличии упорядоченные по времени
    архивы критических данных.

    http://ab57.ru/cmd.html

  • В данной статье будут рассмотрены основы командной строки Windows, а именно:

    • Понятие командной строки;
    • Справочник по командам командной оболочки;
    • Последовательность событий при выполнение команды;
    • Создание сценариев командной строки;
    • Управление отображением текста и команд;
    • Команды для изучение системной информации;
    • Команды для использования реестра;
    • Управление системными службами;
    • Перезагрузка и выключение систем из командной строки;
    • Управление приложениями и  процессами из командной строки.

    Содержание

    1. Понятие командной строки
    2. Краткий справочник по командам командной оболочки (Cmd.exe)
    3. Последовательность событий при выполнение команды
    4. Создание сценариев командной строки
    5. Управление отображением текста и команд
    6. Изучение системной информации
    7. Команды для использования реестра
    8. Управление системными службами
    9. Перезагрузка и выключение систем из командной строки
    10. Управление приложениями, процессами и производительностью

    Понятие командной строки

    Поддержка командной строки встроена в операционную систему Microsoft Windows и доступна через окно командной оболочки. Командная строка поддерживается во всех версиях Windows и служит для запуска встроенных команд, утилит и сценариев. Несмотря на мощь и гибкость командной строки, некоторые администраторы Windows никогда ее не используют. Если вам хватает графических средств администрирования, можно применять только их, щелкая мышью элементы пользовательского интерфейса.

    Однако опытные администраторы Windows, квалифицированные специалисты по технической поддержке и «продвинутые» пользователи не могут обойтись без командной строки. Зная, как правильно применять командную строку, в частности, какие средства командной строки выбрать, как и когда их использовать, чтобы они работали эффективно, можно избежать многочисленных проблем и добиться четкого выполнения операций. Если вы занимаетесь поддержкой нескольких доменов или сетей, то для автоматизации ежедневных операций не только важно, но и необходимо иметь представление об экономящих время способах работы с командной строкой.

    С каждой новой версией Windows командная строка совершенствовалась, а ее возможности расширялись. Командная строка претерпела значительные изменения, связанные не только с повышением производительности, но и с увеличением гибкости. Теперь с помощью командной строки Windows можно решать задачи, которые нельзя было решить в предыдущих версиях Windows.

    Среду командной оболочки Windows запускают разными способами, в частности указывая параметры при запуске Cmd.exe или используя собственный стартовый файл, хранящийся в каталоге %SystemRoot%\System32.

    Кроме того, командная строка может работать в пакетном режиме для выполнения набора команд. В пакетном режиме командная строка считывает и выполняет команды одну за другой.

    Работая с командной строкой Windows, Вы должны понимать, откуда берутся используемые Вами команды. «Родные» команды (встроенные в операционную систему) бывают двух видов:

    • Внутренние – существуют внутри командной оболочки, у них нет отдельных исполняемых файлов;
    • Внешние — реализованы в отдельных исполняемых файлах, которые обычно хранятся в каталоге %SystemRoot% \System32.

    Краткий справочник по командам командной оболочки (Cmd.exe)

    • assoc — выводит или изменяет сопоставления (associations) типов файлов;
    • break — задает точки останова при отладке
    • call — вызывает из сценария процедуру или другой сценарий;
    • cd (chdir) — показывает имя текущего каталога или выполняет смену текущего каталога;
    • cls — очищает окно командной строки и буфер экрана;
    • color — задает цвета текста и фона окна командной оболочки;
    • сору — копирует файлы или выполняет конкатенацию файлов;
    • date — показывает или устанавливает текущую дату;
    • del (erase) — удаляет заданный файл, группу файлов или каталог;
    • dir — показывает список подкаталогов и файлов в текущем или заданном каталоге;
    • echo — выводит текст в окно командной строки или задает, надо ли отображать команды на экране (on|off);
    • endlocal — отмечает конец локализации (локальной области видимости) переменных;
    • exit — выход из оболочки командной строки;
    • for — выполняет заданную команду для каждого файла в наборе;
    • ftype выводит или изменяет текущие типы файлов в сопоставлениях расширений файлов с программами;
    • goto — указывает, что интерпретатор команд должен перейти на строку с заданной меткой в пакетном сценарии;
    • if — выполняет команды по условию;
    • md (mkdir) — создает подкаталог в текущем или заданном каталоге;
    • move — перемещает файл или группу файлов из текущего или заданного исходного каталога в указанный каталог. Также может переименовывать каталог;
    • path — показывает или задает путь к командам, используемый операционной системой при поиске исполняемых файлов и сценариев;
    • pause — останавливает выполнение пакетного файла и ожидает ввода с клавиатуры;
    • popd — делает текущим каталог, имя которого было сохранено командой PUSHD;
    • prompt — указывает, какой текст должен показываться в строке приглашения;
    • pushd — сохраняет имя текущего каталога и при необходимости делает текущим заданный каталог;
    • rd (rmdir) — удаляет каталог или каталог вместе с его подкаталогами;
    • rem — помечает комментарии в пакетном сценарии или Config.nt;
    • ren (rename) — Переименовывает файл или группу файлов;
    • set — показывает текущие переменные окружения или задает временные переменные для текущей командной оболочки;
    • setlocal — отмечает начало локализации (локальной области видимости) переменных в пакетных сценариях;
    • shift — сдвигает позицию замещаемых параметров в пакетных сценариях;
    • start — запускает заданную программу или команду в отдельном окне;
    • time — показывает или устанавливает системное время;
    • title — задает заголовок окна командной оболочки;
    • type — показывает содержимое текстового файла;
    • verify — включает режим проверки файлов после записи на диск;
    • vol — показывает метку и серийный номер дискового тома.

    Синтаксис любой внутренней команды (и большинства внешних) можно получить, введя в командной строке имя команды и /?, например:

       
       copy /?
    
    

    Командная оболочка — весьма мощная среда работы с командами и сценариями. В командной строке можно запускать команды разных типов: встроенные команды, утилиты Windows и версии приложений, рассчитанные на командную строку. Независимо от типа каждая команда, которую вы будете использовать, должна соответствовать одним и тем же синтаксическим правилам. Согласно этим правилам, за именем команды идут обязательные или необязательные аргументы. Кроме того, аргументы могут использовать перенаправление ввода, вывода или стандартных ошибок.

    Последовательность событий при выполнение команды

    • Командная оболочка заменяет любые переменные, введенные в тексте команд, их текущими — значениями;
    • Если введена группа или цепочка из нескольких команд, строка разбивается на отдельные команды, которые в свою очередь разбиваются на имя и аргументы команды. Далее команды обрабатываются по отдельности;
    • Если в имени команды указан путь, командная оболочка ищет команду по этому пути. Если в указанном каталоге такой команды нет, командная оболочка возвращает ошибку;
    • Если в имени команды не задан путь, командная оболочка сначала пытается разрешить имя команды на внутреннем уровне. Если найдена внутренняя команда с таким именем, значит, вызвана внутренняя команда, которую сразу же можно выполнить. Если внутренней команды с таким именем нет, командная оболочка сначала ищет исполняемый файл команды в текущем каталоге, а затем в каталогах, перечне в переменной окружения PATH. Если файла команды нет ни в одном из этих каталогов, командная оболочка возвращает ошибку;
    • Если команда найдена, она выполняется с заданными аргументами и при необходимости ввод считывается из источника, указанного в этих аргументах. Вывод и ошибки команд показываются в окне командной строки или направляются заданному приемнику вывода и ошибок.
    • Как видите, на выполнение команд влияют многие факторы, в том числе пути к командам, перенаправление ввода-вывода, группирование или создание цепочек команд.

    При работе с командной оболочкой Вы, вероятно, запускали ее, открывая меню Start (Пуск) и выбирая Programs (Программы) или All Programs (Все программы), затем Accessories (Стандартные) и Command Prompt (Командная строка). Другие способы запуска командной строки — диалоговое окно Run (Запуск программы) или ввод cmd в другом, уже открытом окне командной оболочки. Эти способы позволяют при запуске командной строки указывать аргументы: ключи, управляющие работой командной строки, и параметры, инициирующие выполнение дополнительных команд. Например, можно запустить командную оболочку в «молчаливом» режиме (т. е. отключить эхо-вывод) командой cmd /q или сделать так, чтобы командная оболочка выполнила заданную команду и завершила свою работу, — для этого нужно ввести cmd /с, а затем текст команды в кавычках.

    В следующем примере командная оболочка запускается, выполняет команду ipconfig с выводом результатов в файл и завершается:

       
       cmd /c "ipconfig > c:\ipconfig.txt"
    
    

    Создание сценариев командной строки

    Сценарии командной строки — текстовые файлы с командами, которые вы хотите выполнить. Это те же команды, которые обычно вводятся в командной оболочке Windows. Однако вместо того чтобы вводить команды каждый раз, когда они понадобятся, можно создать соответствующий сценарий и упростить себе жизнь.

    Поскольку сценарии состоят из стандартных текстовых символов, их можно создавать и редактировать в любом стандартном текстовом редакторе, скажем, в Notepad (блокнот). Вводя команды, убедитесь, что каждая команда или группа команд, которые должны выполняться совместно, разметаются с новой строки. Это обеспечит их корректное выполнение. Закончив создание сценария командной строки, сохраните файл сценария с расширением .bat или .cmd. Оба расширения работают одинаково. Например, если вам надо создать сценарий для вывода имени системы, версии Windows и конфигурации IP, включите в файл SysInfo.bat или SysInfo.cmd следующие три команды:

      
      hostname
      ver
      ipconfig -all
    
    

    Управление отображением текста и команд

    Команда ECHO служит двум целям: для записи текста в вывод (например, в окно командной оболочки или текстовый файл) и для включения/выключения эхо-отображения команд. Обычно при выполнении команд сценария сами команды и вывод этих команд отображаются в консольном окне. Это называется эхо-отображением команд (comand echoing).

    Чтобы использовать команду ECHO для отображения текста, введите echo и текст, который надо вывести:

      
      echo The system host name Is: hostname
    
    

    Чтобы с помощью ECHO управлять эхо-отображением команд, введите echo off или echo on, например:

      
      echo off
      echo The system host name is:
      hostname
    
    

    Чтобы направить вывод в файл, а не в окно командной оболочки, используйте перенаправление вывода, например:

      
      echo off
      echo The system host name is: > current.txt
      hostname » current.txt
    
    

    Теперь посмотрим, как подавляется эхо-отображение команд. Запустите командную оболочку, введите echo off, затем другие команды. Вы увидите, что приглашение командной строки больше не выводится. Вместо него появляется только то, что набирается в консольном окне, и вывод выполненных команд. В сценариях команда ECHO OFF отключает эхо-отображение команд и приглашение командной строки. Добавляя в свои сценарии команду ECHO OFF, вы предотвращаете загромождение окна командной оболочки или файла текстом команд, если Вас интересует лишь вывод от этих команд.

    Изучение системной информации

    Часто при работе с компьютером пользователя или удаленным сервером возникает необходимость в получении базовой информации о системе вроде имени зарегистрированного в ней пользователя, текущего системного времени или местоположения определенного файла. Команды, которые позволяют собрать основную информацию о системе, включают:

    • NOW — отображает текущую системную дату и время в 24-часовом формате, например Sal May 9 12:30:45 2003. Доступна только в Windows Server 2003 Resource Kit;
    • WHOAMI — сообщает имя пользователя, зарегистрированного в системе на данный момент, например adatum\admi-nistrator;
    • WHERE — выполняет поиск файлов по шаблону поиска (search pattern) и возвращает список совпавших результатов.

    Чтобы использовать NOW или WHOAMI, просто введите команду в окне командной оболочки и нажмите Enter. Наиболее распространенный синтаксис для WHERE выглядит так:

      
      where /r базовый_каталог_имя_файла
    
    

    Здесь параметр /r указан для рекурсивного поиска, начиная от указанного каталога (базовый_каталог) и включая все его подкаталоги, а имя_файла — полное или частичное имя искомого файла, которое может включать символы подстановки (wildcards): знак ? заменяет один символ, а знак * — группу символов, например data???.txt или data*.*. В следующем примере в каталоге С:\ и всех его подкаталогах выполняется поиск всех текстовых файлов, имена которых начинаются с data.

       
      where /r C:\ data*.txt
    
    

    Также можно найти файлы всех типов, имена которых начинаются с data:

       
      where /r C:\ data*.*
    
    

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

    • DRIVERQUERY — выводит список всех установленных драйверов устройств и их свойства, в том числе имя модуля (module name), отображаемое имя (display name), тип драйвера и дату сборки (driver link date). В режиме отображения всей информации (/V) сообщается статус (status) и состояние (state) драйвера, режим запуска, сведения об использовании памяти и путь в файловой системе. Параметр /V также включает вывод детальной информации обо всех неподписанных драйверах.
    • SYSTEMINFO — выдает подробную информацию о конфигурации системы, в том числе сведения о версии, типе и изготовителе операционной системы, процессоре, версии BIOS, объеме памяти, региональных стандартах, часовом поясе и конфигурации сетевого адаптера.
    • NLSINFO — отображает подробную информацию о региональных стандартах, включая язык по умолчанию (default language), кодовую страницу Windows, форматы отображения времени и чисел, часовой пояс и установленные кодовые страницы. Эта команда доступна лишь в Windows Server 2003 Resource Kit.

    Чтобы использовать эти команды на локальном компьютере, просто введите имя нужной команды в окне командной оболочки и нажмите Enter.

    Команды для использования реестра

    Реестр Windows хранит конфигурационную информацию операционной системы, приложений, пользователей и оборудования. Эти данные содержатся в разделах (keys) и параметрах (values) реестра, которые размещаются в определенном корневом разделе (root key), который контролирует, как и когда используются разделы и параметры.

    Если Вы знаете пути к разделам и понимаете допустимые типы данных в разделах, то можете использовать команду REG для просмотра разделов и параметров и манипуляций над ними самыми разнообразными способами. REG поддерживает несколько подкоманд:

    • REG add — добавляет в реестр новый подраздел или элемент;
    • REG delete — удаляет из реестра подраздел или элемент;
    • REG query — выводит список элементов раздела и имена подразделов (если они есть);
    • REG compare — сравнивает подразделы или элементы реестра;
    • REG сору — копирует элемент реестра по указанному пути раздела на локальной или удаленной системе;
    • REG restore — записывает в реестр ранее сохраненные подразделы, элементы и параметры;
    • REG save — сохраняет копию указанных подразделов, элементов и параметров реестра в файл.

    Управление системными службами

    Службы обеспечивают ключевые функции рабочих станций и серверов. Для управления системными службами на локальных и удаленных системах используется команда контроллера служб (service controller command) SC, имеющая набор подкоманд, ниже описывается лишь их часть:

    • SC config — настройка учетных записей регистрации и запуска служб;
    • SC query — вывод списка всех служб, настроенных на компьютере;
    • SC qc — отображение конфигурации определенной службы;
    • SC start — запуск служб;
    • SC stop — остановка служб;
    • SC pause — приостановка работы служб;
    • SC continue — возобновление работы служб;
    • SC failure — задание действий, выполняемых при сбое службы;
    • SC qfailure — просмотр действий, выполняемых при сбое службы.

    Во всех командах можно указывать имя удаленного компьютера, со службами которого Вы хотите работать. Для этого вставьте UNC-имя или IP-адрес компьютера перед используемой подкомандой. Вот синтаксис:

      
      sc ИмяСервера Подкоманда
    
    

    Перезагрузка и выключение систем из командной строки

    Системы нередко приходится перезагружать или выключать. Один из способов — использовать для этого утилиту Shutdown, которая позволяет работать с локальной и удаленными системами. Другой способ управлять выключением или перезагрузкой системы — назначить задание для выключения. Здесь можно использовать Schtasks, чтобы указать время выключения, или создать сценарий со списком команд выключения для индивидуальных систем.

    Управлять перезагрузкой и выключением локальной системы позволяют следующие команды.

    Выключение локальной системы:

      
      shutdown /s /t ЗадержкаВыключения /1 /f
    
    

    Перезагрузка локальной системы:

      
      shutdown /r /t ЗадержкаВыключения /1 /f
    
    

    Управление приложениями, процессами и производительностью

    Всякий раз, когда операционная система или пользователь запускает службу, приложение или команду, Microsoft Windows запускает один или более процессов для управления соответствующей программой. Несколько утилит командной строки упростят вам мониторинг программ и управление ими. К этим утилитам относятся:

    • Pmon (Process Resource Manager) — показывает статистические данные по производительности, включая использование памяти и процессора, а также список всех процессов, выполняемых в локальной системе. Позволяет получать детальные «снимки» задействованных ресурсов и выполняемых процессов. Pmon поставляется с Windows Resource Kit;
    • Tasklist (Task List) — перечисляет все выполняемые процессы по имени и идентификатору процесса, сообщает информацию о сеансе пользователя и занимаемой памяти;
    • Taskkill (Task Kill) — останавливает выполнение процесса, заданного по имени или идентификатору. С помощью фильтров можно останавливать процессы в зависимости от их состояния, номера сеанса, процессорного времени, занимаемой памяти, имени пользователя и других параметров.

    Вот в принципе все, что я хотел рассказать об основах командной строки Windows.

    • Введение
    • Определение
    • MS-DOS batch
      • Зачем нужны bat-файлы
      • Передача параметров
      • Использование кавычек
      • Экранирование спецсимволов
      • Получение свойств файла сценария
      • Перенаправление вывода в файл
      • Использование функций
      • Чтение конфигурационного файла
      • Конвейеры
      • Сценарий «Установка программы»
      • Сценарий «Распаковка всех архивных файлов»
      • Сценарий «Создание загрузочного диска»
      • Сценарий «Разметка и форматирование диска»
      • Сценарий «Настройка компьютера»

    В работе системного администратора встречается много рутинной работы. Естественно, человек всегда ищет способы автоматизации своей работы. Администратору для решения задач оптимизации своей работы помогают скрипты (сценарии).

    В данной статье я хочу рассказать о скриптах для операционных систем семейства Windows. Конечно, сейчас очень сильно развиты языки высшего уровня, различные автоматические оптимизаторы и оболочки, но, как я считаю, администратор должен уметь работать с командной строкой и знать операционную систему, в которой он работает. Эта статья не будет построена на голой теории, я не буду углубляться в механизмы работы той или иной команды, мы рассмотрим основные команды двух оболочек сценариев, встроенных в операционную систему, а так же посмотрим основные возможности скриптовых языков.

    Скриптовый язык (scripting language) — это язык программирования, разработанный для записи «сценариев», последовательности операций, которые пользователь может выполнять на компьютере.

    То есть скрипты могут повторить практически все операции, которые пользователь выполняет на компьютере:

    • Сконфигурировать систему;
    • Сконфигурировать профиль пользователя;
    • Установить или удалить программу;
    • Собрать статистику работы компьютера или пользователя;
    • Сделать резервные копии файлов;
    • Другие операции.

    Конечно, все эти операции можно осуществить либо вручную, либо через язык программирования высокого уровня, тем не менее, не стоит забывать и о сценариях, как о простом методе выполнения процедур, доступном для любого пользователя. Скриптовый язык предпочтительнее применять, если:

    • нужна прозрачность кода сценария, сценарии обычно распространяются с открытым кодом, и любой пользователь может посмотреть, какие команды будет выполнять сценарий;
    • нужно обеспечить стабильность системы, неправильно написанный скрипт выведет диагностическое сообщение, а не приведёт систему к краху;
    • требуется дать пользователям возможность самостоятельно изменять переменные сценария и процедуры;
    • нужно использовать процедуры определенной программы, которые проще осуществить через сценарии, чем осуществлять интерфейс между приложениями;
    • требуется кроссплатформенность — возможность исполнять сценарий на разных операционных системах или в разных браузерах.

    Итак, в зависимости от способа реализации сценария и универсальности использования этого сценария, скрипты делятся на нескольких типов:

    • Универсальные — скрипты, которые выполняются независимо от платформы, такие скрипты требуют компиляции, примеры таких языков: Perl (Practical Extraction and Report Language), Python, PHP (Hypertext Preprocessor).
    • Интегрированные в приложение — это скрипты, которые разработаны и работают только внутри определенной программы, явный представитель этого класса — VBA (Visual Basic for Applications).
    • Оболочки — скрипты, которые работают в специальной среде выполнения команд, членам этой группы являются такие скриптовые языки как sh, bash (Bourne shell), bat (MS-DOS batch).
    • Встраиваемые — это языки, которые можно интегрировать в различные приложения, такие языки имеют жесткие стандарты для того, чтобы любая программа, в которую будет интегрирован сценарий, смогла выполнить этот сценарий, примерами таких языков являются js (Java Script), vbs (Visual Basic Script).

    В этой статье я рассмотрю два скриптовых языка: «MS-DOS batch» и » Visual Basic Script». Все приведенные примеры я использовал в своей работе, хотя для написания статьи они немного упрощены. Кстати, сценарии очень удобно применять в групповых политиках, в запланированных заданиях и в таком продукте, как Microsoft System Management Server 2003 (MS SMS 2003).

    Bat-файлы — это наиболее быстрый и простой способ автоматизации действий пользователя. Такой тип сценариев обычно используется чтобы:

    • создать скрипт как можно быстрее;
    • видеть ход выполнения сценария;
    • видать результаты работы скрипта на экране;
    • знать, когда скрипт закончит работу;
    • вызвать внешнее приложение в ходе работы скрипта.

    В основном bat-файлы применяется для копирования и удаления файлов, составления отчетов, запуска других программ и скриптов. Наиболее часто используемые команды:

    • копирование файлов и каталогов: copy, xcopy;
    • перемещение файлов: move;
    • удаление файлов и каталогов: del, rd;
    • создание каталогов: md;
    • перемещение по файловой системе: cd;
    • информация о содержимом файлов и каталогов: type, dir;
    • запуск оболочки и выход из нее: cmd, exit;
    • вызов внешних приложений, циклы и условия: call, for, goto, if, set;
    • дополнительные команды: at, net, set, cls.

    Чтобы получить полный список команд, доступных в Вашей операционной системе, надо вызвать командную строку и выполнить команду «help» (надеюсь, что читатели знают, как запустить командную строку в Windows):

    C:\>help
    

    Чтобы из команд получился сценарий, нужно построчно написать список команд в текстовый файл и сохранить этот файл с расширением «bat».

    Какими бы примитивными не казались bat-файлы, c помощью них можно сильно автоматизировать работу. Мало того, такие сценарии поддерживают передачу переменных через командную строку. Например, чтобы обработать какой-то файл, нужно, чтобы сценарий знал, какой именно файл нужно обработать. Конечно, можно прописать имя обрабатываемого файла непосредственно в коде, но тогда мы получим неуниверсальный скрипт. Чтобы избежать этого, нужно использовать передачу переменных:

    • в теле сценария использовать обращение к переданной переменной;
    • при вызове скрипта передавать ему переменную или список переменных через пробел.

    Тело сценария Test.bat:

    REM отключение вывода команд на экран
    @echo OFF
    REM вывод на экран переданной в переменной
    echo %1
    REM остановка в ходе выполнения сценария
    pause
    

    Вызов сценария:

    C:\>Test.bat MyParameter
    

    Очень часто в путях к внешним приложениям употребляются пробелы, например, если программа находится в каталоге «Program Files». В таких случаях путь к файлу должен быть заключен в кавычки, иначе интерпретатор сценария сочтет, что вы ввели две команды, разделенных пробелами. Пример использования кавычек:

    call "C:\Program Files\Movie Maker\moviemk.exe"
    call "C:\My Folder\test.bat" "C:\My Catalog\archive.zip"
    

    В командном языке существует некоторый набор символов, которые всегда трактуются как спецсимволы. К ним, в частности, относятся:

    • операторы перенаправления ввода-вывода <, >, >>;
    • оператор конвейера |;
    • операторы объединения команд ||, & и &&;
    • оператор переменной %…%.

    Чтобы применять вышеперечисленные символы в своих целях, их нужно экранировать символом «^». То есть, если Вам требуется вставить символ в текст своей команды, то это будет выглядеть так:

    echo ^<html^>                                    >mytest.html
    echo ^<head^>                                   >>mytest.html
    echo ^<title^>My test page^</title^>            >>mytest.html
    echo ^</head^>                                  >>mytest.html
    echo ^<body^>                                   >>mytest.html
    echo Hello World!                               >>mytest.html
    echo ^</body^>                                  >>mytest.html
    echo ^</html^>                                  >>mytest.html
    

    Еще одним полезным свойством символа «^» является перенос строк. То есть, если ваша команды слишком длинные, то это обстоятельство уменьшает удобочитаемость сценария. Чтобы вся команда убиралась в экран редактора, применим перенос строки:

    oscdimg -m -n -h -lDeployment -bC:\Common\DeploymentDisk\winpe_x86\etfsboot.com ^
     C:\Common\DeploymentDisk\winpe_x86\ISO C:\Common\DeploymentDisk\winpe_x86\^
     Deployment.iso
    

    Очень часто разработчику необходимо знать путь, откуда сценарий был запущен. В решении этой задачи ему помогают специальные переменные:

    • %~0 — возвращает путь к сценарию, удаляя кавычки
    • %~f0 — возвращает полный квалифицированный путь к сценарию
    • %~d0 — возвращает в букву диска, откуда запущен сценарий
    • %~p0 — возвращает путь к сценарию
    • %~n0 — возвращает имя файла сценария
    • %~x0 — возвращает расширение файла сценария
    • %~s0 — возвращает путь к сценарию в коротком формате
    • %~a0 — возвращает атрибуты файла сценария
    • %~t0 — возвращает в дату и время создания файла сценария
    • %~z0 — возвращает размер файла сценария

    Указанные модификаторы можно объединять. Например, чтобы получить полный путь к директории, откуда был запущен сценарий, нужно применить в тексте сценария такой модификатор «%~dp0»:

    REM отключение вывода команд на экран
    @echo OFF
    REM вывод на экран месторасположения файла сценария
    echo %~dp0
    REM остановка в ходе выполнения сценария
    pause
    

    Интерпретатор сценариев таким образом может обработать не только путь к файлу сценария, но и пути, переданные в качестве параметров. Чтобы применить модификаторы к переданному параметру, необходимо указать его порядковый номер в командной строке. Как уже понятно из предыдущего примера, нулевым параметром является сам сценарий, а все остальные переданные переменные нумеруются от 1 до 9:

    REM отключение вывода команд на экран
    @echo OFF
    REM вывод на экран имени файла, переданного в качестве переменной
    echo %~nx1
    REM остановка в ходе выполнения сценария
    pause
    

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

    Обычно каждая команда из сценария выводит результат своей работы в окно консоли. Если необходимо сохранить журнал выполнения скрипта, то для этого используют перенаправление вывода в файл:

    • команда >файл — перенаправить вывод в файл с удалением старого содержимого файла;
    • команда >>файл — перенаправить вывод в файл c дописыванием в конец файла.

    Иногда bat-файлы вырастают до довольно больших размеров, тогда перенаправление в файл очень загромождает код сценария — почти каждая строка имеет хвостик типа >>файл. Правильнее было бы перенаправить стандартный вывод в файл, чтобы все, что выводится на экран, автоматически попадало в файл вывода. Сделать это можно следующим образом:

    REM отключение вывода команд на экран
    @echo OFF
    REM установка значения переменной имени файла вывода
    set OUTPUT=mytest.html
    REM задание вывода работы сценария в файл вывода
    if "%STDOUT_REDIRECTED%" == "" (
       set STDOUT_REDIRECTED=yes
       cmd.exe /c %0 %* >%OUTPUT%
       exit /b %ERRORLEVEL%
    )
    REM тело сценария
    echo ^<html^>
    echo ^<head^>
    echo ^<title^>My test page^</title^>
    echo ^</head^>
    echo ^<body^>
    echo Hello World!
    echo ^</body^>
    echo ^</html^>
    

    В этом примере сценарий проверяет задана ли переменная окружения STDOUT_REDIRECTED. Если она не установлена, то сценарий перезапускает сам себя, предварительно устанавливая эту переменную и останавливая выполнение остальных команд из тела скрипта. Если переменная STDOUT_REDIRECTED установлена, значит, сценарий уже перезапущен с перенаправленным выводом, и можно перейти к телу сценария. Такое перенаправление дает еще одно преимущество — файл открывается и закрывается только один раз, а всем командам передается ссылка на уже открытый файл.

    Иногда требуется, чтобы сценарий вообще ничего не выводил ни на экран, ни в файл. Добиться такого результата можно с помощью отключения вывода команд на экран и перенаправления результатов команд в ноль.

    REM отключение вывода команд на экран
    @echo OFF
    REM перенаправление результатов команд в ноль
    copy text.txt test2.txt >nul
    

    Иногда может потребоваться обрабатывать какой-то параметр несколько раз за один проход сценария. Конечно, можно несколько раз написать код для обработки переменной, но более красивым решением было бы применение функций. Функции объявляются и описываются после основной части сценария, вызов функции производится командой call, а выход из нее — exit. Простой пример использования функции:

    REM отключение вывода команд на экран
    @echo OFF
    REM вызов функции
    call :GetSum %1 %2 -30
    REM вывод результатов на экран
    echo (%1 + %2 - 30) = %RESULT%
    REM остановка в ходе выполнения сценария
    pause
    REM окончание основной программы, выход из сценария
    exit
    REM функция суммирования
    :GetSum
       if %1 == 0 (
           set /a RESULT=%2+%3
           exit /b
       )
    set /a RESULT=%1+%2+%3
    exit /b
    

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

    # Файл с настройками
    # Первое число
    Value1=23
    # Второе число
    	Value2=15
    

    Чтобы его прочитать, воспользуемся следующим сценарием:

    @echo OFF
    REM Вызов функции считывания текстового файла config.txt
    call :read_config "%~dp0\config.txt" || exit /b 1
    REM Вывод считанных параметров на экран
    echo Build mode  : %Value1%
    echo Compiler    : %Value2%
    REM окончание основной программы, выход из сценария
    exit /b 0
    REM функция считывания текстового файла
    :read_settings
    set ConfigFile=%1
    REM Проверка существования файла
    if not exist %ConfigFile% (
       echo FAIL: Файл с настройками отсутствует
       exit /b 1
    )
    REM Обработка файла
    REM   eol=# - указывает, что строку надо пропустить - это комментарий
    REM   delims== - указывает разделитель - это символ "="
    REM   tokens= - указывает как распределить разделенные переменные
    for /f "eol=# delims== tokens=1,2" %%i in (%ConfigFile%) do (
       set %%i=%%j
    )
    exit /b 0
    

    Конвейеры — это операторы, которые позволяют командам работать совместно. Обратите внимание на строку вызова функции в предыдущем примере — в ней присутствует конвейер «||». Давайте рассмотрим, какие же конвейеры могут использоваться в bat-файлах:

    • < — ввод в первую команду результатов выполнения второй программы;
    • | — передача выхода первой команды непосредственно на вход другой;
    • || — выполнение второй команды только в том случае, если первая дала сбой;
    • & — выполнение второй команды после выполнения первой;
    • && — выполнение второй команды только в том случае, если первая выполнена успешно.

    Данный пример осуществляет поиск каталога или файла, в название которого входит слово «Accessories».

    dir "C:\Program Files" /S | find "Accessories"
    

    Конвейер команд состоит из двух частей: первая команда выводит все файлы и каталоги папки «C:\Program Files» (дополнительный параметр «/S» означает, что нужно обработать и подпапки), вторая команда получает результат выполнения первой через оператор конвейера «|» и осуществляет поиск слов «Accessories».

    На этом я закончу разбор операторов командной строки и приведу несколько сценариев bat-файлов из моей практики.

    Данный сценарий разработан для установки программы Autodesk DWG True View. Установочный пакет и скрипт размещаются на сервере. Чтобы установить программу на компьютер пользователя, нужно подключить сетевой ресурс на требуемом компьютере и запустить bat-файл.

    REM отключение вывода команд на экран
    @ECHO OFF
    REM задание заголовка окна оболочки
    TITLE Autodesk DWG True View
    REM запуск установочного файла в режиме пассивной установки
    "%~DP0DWGViewer.msi" /passive
    REM копирование чертежа на рабочий стол пользователей
    COPY "%~DP0Draw.dwg" "%ALLUSERSPROFILE%\Desktop"
    

    Здесь используются такие параметры как:

    • %~DP0 — подстановка пути месторасположения сценария;
    • %ALLUSERSPROFILE% — подстановка пути общего профиля пользователей;
    • package.msi/passive — установка MSI-пакета в пассивном режиме — установка «По умолчанию» без окон подтверждения.

    Данный сценарий разработан для распаковки всех архивов, находящихся в одной папке, в указанную директорию. Приложение-распаковщик, папка с архивами и папка для распакованных файлов находятся в той же директории, что и сценарий. Чтобы установить распаковать архивы, нужно запустить bat-файл.

    REM отключение вывода команд на экран
    @ECHO OFF
    REM проверка, что папка для распаковки существует, удаление папки
    IF EXIST "%~DP0Extracts" RD "%~DP0Extracts" /S /Q
    REM создание папки для распаковки
    MD "%~DP0Extracts"
    REM распаковка всех 7z-файлов из папки Archives в папку Extracts
    FOR %%a IN ("%~DP0Archives\*.7z") DO CALL "%~DP07z.exe" e "%%a" -o"%~DP0Extracts" -r
    

    Здесь используются такие процедуры как:

    • IF EXISTfolder- поверка существования папки или файла;
    • %~DP0 — подстановка пути месторасположения сценария;
    • RDfolder/S /Q — удаление каталога без вывода на экран подтверждения на удаление
    • FOR %%a IN (folder\mask) DO — цикл перебора всех элементов в выбранном списке;
    • CALLapplication»%%a» — вызов внешнего приложения и передача ему параметра из цикла.

    Данный сценарий разработан для создания загрузочного диска с помощью пакета Microsoft Windows Automated Installation Kit. Запускается из командной строки указанного выше пакета. Результатом работы сценария является загрузочный ISO-образ, который впоследствии можно записать на DVD и использовать для установки или восстановления системы. Более подробно о создании такого диска будет рассказано в одной из следующих статей.

    REM копирование заготовки загрузочного диска
    copype.cmd x86 c:\DeploymentDisk\winpe_x86
    REM монтирование заготовки для изменения
    imagex /mountrw c:\DeploymentDisk\winpe_x86\winpe.wim 1 c:\DeploymentDisk\^
     winpe_x86\mount
    REM внедрение в заготовку необходимых пакетов
    peimg /install=WinPE-Scripting-Package c:\eploymentDisk\winpe_x86\mount\^
     Windows
    peimg /install=WinPE-HTA-Package c:\DeploymentDisk\winpe_x86\mount\Windows
    peimg /install=WinPE-WMI-Package c:\DeploymentDisk\winpe_x86\mount\Windows
    peimg /install=WinPE-XML-Package c:\DeploymentDisk\winpe_x86\mount\Windows
    REM вывод на экран установленых в заготовку пакетов
    peimg /list c:\DeploymentDisk\winpe_x86\mount\Windows
    REM внедрение в заготовку дополнительных драйверов
    peimg /inf=C:\DeploymentDisk\winpe_tools\Drivers\*.inf c:\DeploymentDisk\^
     winpe_x86\mount\Windows
    REM подготовка заготовки к записи на диск
    peimg /prep /f c:\DeploymentDisk\winpe_x86\mount\Windows
    REM копирование дополнительных программ в заготовку
    xcopy C:\DeploymentDisk\winpe_tools\Starter c:\DeploymentDisk\winpe_x86\^
     mount\ /S /Y
    xcopy C:\DeploymentDisk\winpe_tools\winpe.bmp C:\DeploymentDisk\winpe_x86\^
     mount\Windows\System32\ /Y
    xcopy C:\DeploymentDisk\winpe_tools\winpeshl.ini C:\DeploymentDisk\winpe_x86\^
     mount\Windows\System32\ /Y
    REM размонтирование заготовки
    imagex /unmount /commit c:\Common\DeploymentDisk\winpe_x86\mount
    REM копирование готового загрузчика в папку ISO-проекта
    xcopy /y C:\DeploymentDisk\winpe_x86\winpe.wim C:\DeploymentDisk\winpe_x86\^
     ISO\sources\boot.wim
    REM копирование дополнительных программ в ISO-проект
    xcopy C:\DeploymentDisk\winpe_tools\FarManager C:\DeploymentDisk\winpe_x86\^
     iso\FarManager\ /S /Y
    xcopy C:\DeploymentDisk\winpe_tools\Starter C:\DeploymentDisk\winpe_x86\iso\^
     Starter\ /S /Y
    xcopy C:\DeploymentDisk\winpe_tools\Deployment C:\DeploymentDisk\winpe_x86\iso\^
     Deployment\ /S /Y
    REM создание ISO-образа загрузочного диска
    oscdimg -m -n -h -lDeployment -bC:\Common\DeploymentDisk\winpe_x86\etfsboot.com ^
     C:\Common\DeploymentDisk\winpe_x86\ISO C:\Common\DeploymentDisk\winpe_x86\^
     Deployment.iso
    

    Здесь используются такие процедуры Microsoft Windows Automated Installation Kit как:

    • copype.cmd — сценарий копирования заготовки диска;
    • imagex — утилита редактирования образа операционной системы;
    • peimg — утилита подготовки образа операционной системы;
    • oscdimg — утилита создания ISO-образов;

    Этот сценарий разработан для разметки и форматирования диска компьютера перед установкой операционной системы. Скрипт в основном запускают в специальной прединсталляционной операционной системе Windows PE, например в такой, какая была собрана в предыдущем примере.

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

    REM отключение вывода команд на экран
    @ECHO OFF
    REM создание новой дисковой структуры
    ECHO "Creating the new disk structure"
    DISKPART.EXE /S "%~DP0DiskPart00.txt">nul
    REM создание файловой сиситемы
    ECHO "Formating the disk"
    ECHO Y | FORMAT C: /Q /FS:NTFS /V:>nul
    REM вывод на экран результатов обработки диска
    DISKPART.EXE /S "%~DP0DiskPart01.txt"
    ECHO "The disk partitioning is completed. Please review the log in this window."
    PAUSE
    

    В этом примере используются:

    • DISKPART.EXE — утилита разметки диска, которая использует внешние сценарии (эти сценарии приведены ниже);
    • конвейер «|» — на вход команды «FORMAT» подается значение «Y», что позволяет избежать участия пользователя в работе сценария;
    • FORMAT — команда форматирования диска, использующая ключи, которые определяют, что нужно отформатировать диск С: в формате NTFS в быстром режиме и без метки диска;
    • >nul — перенаправление результатов команд в ноль.

    Сценарий разметки диска:

    select disk 0
    clean
    create partition primary
    select partition 1
    active
    assign letter=C
    

    Сценарий вывода информации о диске:

    select disk 0
    select partition 1
    detail partition
    

    Кстати, два последних сценария являются интегрированными скриптами — они работают только внутри программы DISKPART.EXE.

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

    REM отключение вывода команд на экран
    @ECHO OFF
    REM создание меню быстрого запуска
    IF NOT EXIST "%SYSTEMDRIVE%\Documents and Settings\Default User\Application Data\^
     Microsoft\Internet Explorer\Quick Launch\" MD "%systemdrive%\^
     Documents and Settings\Default User\Application Data\Microsoft\^
     Internet Explorer\Quick Launch\"
    REM установка классического входя в систему
    REGEDIT /S "%~DP0Classic_Login.reg"
    REM удаление ярлыка на центр обновления Windows
    IF EXIST "C:\Documents and Settings\All Users\Start Menu\Windows Update.lnk"^
     DEL "C:\Documents and Settings\All Users\Start Menu\Windows Update.lnk">nul
    REM остановка сервиса Windows Management Instrumentation
    NET STOP "WINMGMT" /Y>nul
    REM удаление репозитория сервиса Windows Management Instrumentation
    DELTREE /Y "%SystemRoot%\System32\WBEM\Repository">nul
    REM запуск сервиса Windows Management Instrumentation
    NET START "WINMGMT" /Y>nul
    REM регистрация путей драйверов
    CSCRIPT "%~DP0DevicePath.vbs"
    REM перемещение утилиты robocopy.exe в системный каталог
    MOVE /Y "%~DP0robocopy.exe" %SystemRoot%\System32
    REM добавление администраторов компании в локальные администраторы компьютера
    CSCRIPT "%~DP0AddAccountToAdmins.vbs" "DOMAIN\Site Admins"
    REM замена ссылок "по умолчанию" на ссылки сервера компании
    "%~DP0REGFIND.exe" -b -y \\DefaultServer\Distrib$ -r \\SiteServer\Distrib$
    "%~DP0REGFIND.exe" -b -y http://u18.eset.com:8081 -r http://SiteServer.domain.com:8081
    REM установка клиента MS SMS 2003
    MSIEXEC /i "%~DP0client.msi" /passive
    REM подписывание клиента MS SMS 2003 к серверу компании
    CSCRIPT "%~DP0AssignSMSClient.vbs"
    REM очистка журнала компьютера
    CSCRIPT "%~DP0ClearEventLogs.vbs"
    REM удаление временной папки
    RD /S /Q C:\Temp
    REM удаление сценариев настройки компьютера
    DEL /q "%~DP0ClearEventLogs.vbs"
    DEL /q "%~DP0regfind.exe"
    DEL /q "%~DP0DevicePath.vbs"
    DEL /q "%~DP0AddAccountToAdmins.vbs"
    DEL /q "%~DP0client.msi"
    DEL /q "%~DP0AssignSMSClient.vbs"
    REM перезагрузка компьютера
    CSCRIPT "%~DP0\Reboot.vbs"
    

    Здесь использованы такие команды и внешние модули как:

    • IF NOT EXIST folder command — проверка на существование папки;
    • REGEDIT file — слияние файла с реестром;
    • NET STOP — остановка сервиса;
    • NET START — запуск сервиса;
    • CSCRIPT — выполение VBS-сценария в консольном режиме;
    • REGFIND — утилита поиска и замены значений реестра;
    • MSIEXEC — утилита распаковки MSI-пакета.

    Итак, давайте подведем итог: для чего применяются bat-сценарии, что с их помощью можно сделать, какие ограничения имеют такие сценарии:

    • сценарии не требуют компиляции и их код в любой момент можно отредактировать;
    • BAT-сценарии просты и быстры в написании;
    • BAT-файлы выполняются в консоли, поэтому пользователь видит ход выполнения сценария, и знает, когда сценарий закончит свою работу;
    • эти скрипты, в основном, применяются для копирования файлов и для запуска других приложений;
    • BAT-файлы ограничены в функциональности и не могут выполнять сложных задач;
    • такие сценарии могут выполняться только в консоли MS DOS.

    Продолжение следует…

    Виталий Бочкарев

    Мы все любим писать серьезные вещи на серьезных языках. Шаблоны, 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
    

    Помните лишь, что чудо-символ должен быть последним в строке – скажите «Нет!» концевым пробелам.

    Как определить имя каталога, в котором находится запущенный командный файл?

    Иногда сценарию надо знать полный путь к себе самому и/или к каталогу, в котором он находится. Это может понадобиться по разным причинам. Например, он должен достать из системы контроля версий исходники в каталог <script-dir>/src рядом с собой. Или, запускаются тесты из каталога <script-dir>/tests, и перед их запуском надо добавить каталог <script-dir>/bin в переменную PATH.

    Можно, конечно, рассчитывать на то, что командный файл был вызван из того же каталога, где он находится, и тогда в качестве вышеупомянутого <script-dir> можно использовать переменную окружения %CD% — полный путь к текущему каталогу. Однако любые допущения в нашем деле недопустимы (хороший каламбур, однако!). Поэтому приведу более надежное решение.

    Прежде всего, вспоминаем, что переменная %0 в bat-файле соответствует нулевому аргументу командной строки, т.е. имени самого файла. После этого читаем скудную документацию для команды 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
    

    Таким образом, правильным будет использовать в качестве тега <script-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        - expanded path contains short names only
    

    который нам как раз мог бы помочь. Но есть засада – все эти полезные префиксы нельзя использовать с произвольной переменной окружения, а присваивание переменным %0 — %9 не поддерживается. К счастью, описываемые префиксы можно еще использовать с переменными цикла for, и это дает нам способ достичь требуемого результата. Например, вот так можно получить 8.3-путь к “Program Files”:

    for /d %%i in ("%PROGRAMFILES%") do (
        set PROGRAMFILESSHORT=%%~si
    )
    
    echo 8.3-имя для каталога "%PROGRAMFILES%" -^> "%PROGRAMFILESSHORT%"
    

    Этот и другие модификаторы можно использовать и с любой другой формой цикла 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 часа жизни…

    Как сложить два числа?

    Краткий ответ – смотри:

    Длинный ответ таков. В bat-файлах можно производить довольно-таки продвинутые вычисления – продвинутые не в сравнении с другими языками, а в сравнении с отсутствием возможности что-либо вычислить вообще. Вычисление осуществляется командой set, если она выполняется с ключом /a. Поддерживается практически полный набор операторов языка C, включая шестнадцатеричный модификатор 0x. Переменные окружения в выражении не обязательно заключать в знаки процента – все, что не является числом, считается переменной. Подробнее – все-таки в man set, тьфу, то есть в set /?. А здесь напоследок – просто несколько примеров.

    @echo off
    
    set ARG=1
    
    remset /a RESULT=ARG + 2
    echo %RESULT%
    
    rem rem 
    set /a RESULT="ARG << 2"
    echo %RESULT%
    
    rem set /a RESULT=0x1234 + 0x6786
    echo %RESULT%
    
    rem
    

    Да, можно. Более того, иногда даже нужно. Правда, функциями это можно назвать условно. Есть особый синтаксис команды call, который позволяет перейти на метку в этом же bat-файле с запоминанием места, откуда был произведен этот вызов:

    Возврат из функции производится командой:

    exit /b [опциональный код возврата]
    

    Ключ /b здесь очень важен: без него будет произведен выход не из функции, а из сценария вообще.

    За подробностями обращайтесь к:

    Что интересно, команда call с таким синтаксисом поддерживает рекурсивные вызовы с автоматическим созданием нового фрейма для переменных аргументов %0-%9. Иногда это может быть полезным. Вот классический пример рекурсивного подсчета факториала на командном языке:

    @echo off
    
    call :factorial %1
    echo %RESULT%
    exit
    
    remremremremrem: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 строк является ярким лозунгом в поддержку работы Дейкстры «О вреде оператора goto». Мешанина из переходов вперед и назад действительно является кодом «только для записи». Можно ли что-то предпринять по этому поводу?

    На самом деле можно. Как правило, большинство меток и переходов используются для организации ветвлений при проверке условий, т.е. банальных if-then-else блоков. В оригинале, bat-язык поддерживал только одну команду в блоке then, что автоматически приводило к идиомам вида:

    if condition goto :THEN
    remremgoto IF_END
    :THEN
    remrem:IF_END
    

    Но к счастью, командный интерпретатор cmd.exe современных ОС Windows 2000 и старше поддерживает блоки команд в конструкциях ветвления, что устраняет необходимость применения меток. Блоки команд заключаются в круглые скобки. Выглядит это так (имитируя C/C++ indentation style):

    if condition (
        rem    rem) else (
        rem    rem)
    

    Конкретный пример использования:

    @echo off
    
    set BUILDMODE=%1
    
    if "%BUILDMODE%" == "" (
        echo FAIL: Аргумент является обязательным ^(--debug, --release^)
        exit /b 1
    )
    
    remset 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
    
    rem
    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=release
    
    compiler=cl.exe
    
    arch=x86
    

    Ничего сверхъестественного – простой key=value формат с возможностью вставки Unix-style комментариев. Помочь в чтении и обработке этого файла нам сможет команда for. Ее дополнительные опции позволяют задать и разделители, и символ начала комментария, и кое-что еще. Вот командный файл, который выполняет поставленную задачу:

    @echo off
    
    remremremcall :read_settings %~dp0\settings.txt || exit /b 1
    
    remecho Build mode  : %BUILDMODE%
    echo Compiler    : %COMPILER%
    echo Architecture: %ARCH%
    
    remexit /b 0
    
    remremremrem:read_settings
    
    set SETTINGSFILE=%1
    
    remif not exist %SETTINGSFILE% (
        echo FAIL: Файл с настройками отсутствует
        exit /b 1
    )
    
    remremremremremremremremremrem
    for /f "eol=# delims== tokens=1,2" %%i in (%SETTINGSFILE%) do (
        rem    rem    rem    set %%i=%%j
    )
    
    exit /b 0
    

    Обильные комментарии должны помочь легко разобраться, что к чему. За подробностями, как обычно, отошлю к:

    Кстати, возможности команды 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
    

    Форма этих операторов весьма соответствует их содержанию. В случае, пожалуй, наименее полезного оператора & вторая команда будет просто выполнена после первой, т.е. это равносильно простой записи:

    Оператор && гарантирует, что вторая команда будет выполнена только, если первая была выполнена успешно, т.е. с нулевым кодом возврата (он же %errorlevel%). Такие конструкции очень популярны в мире shell-сценариев Unix. Например:

    Я был приятно удивлен, узнав, что cmd.exe тоже умеет выполнять такие конструкции. Это безопаснее и правильнее, нежели простое последовательное выполнение этих команд, и короче и проще, чем строгая проверка и обработка кодов возврата. Очень удобно при написании на скорую руку. Не менее полезен иногда и оператор ||. Суть его тоже логична – выполнить вторую команду, если первая дала сбой. Часто встречается в таких идиомах:

    Если перейти в каталог sources не удастся, то будет произведен выход с кодом ошибки 1. Если же первая команда отработает нормально, то вторая выполнена не будет. Например, такая простейшая защита помогла бы в случае с cd по UNC-адресу, описанному ранее.

    Можно ли написать на bat-языке серьезную программу?

    Пожалуй, нет. Серьезная программа должна все-таки выглядеть серьезно. А все написанное на командном языке Windows таковым назвать можно лишь с о-о-о-чень большой натяжкой. Так что для решения более сложных задач автоматизации лучше все-таки взять что-нибудь более функциональное:

    • Perl
    • Python
    • Ruby
    • JScript / VBScript

    Последние, кстати, присутствуют в Windows 2000/XP по умолчанию (с некоторыми функциональными различиями) и в целом могут считаться заменой *.bat языку. Однако сдается мне, что *.bat-файлы проживут еще очень долго.

    Дай Бог, чтобы я ошибся…

    Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии
  • Командная строка windows вики
  • Командная строка windows 10 как перейти на другой диск
  • Intel core i3 370m windows 10
  • Устройства bluetooth не работают на компьютере под управлением windows 7
  • Программа для назначения клавиш для windows