1 что такое язык оболочки командной строки
Перейти к содержимому

1 что такое язык оболочки командной строки

  • автор:

1 что такое язык оболочки командной строки

Интерпретатор командной строки, или shell (shell — оболочка) — эта та программа, которая принимает команды от пользователя и исполняет их.

  • Взаимодействие с пользователем (редактирование командной строки, история команд и т.д.).
  • Обработка (расширение) шаблонов имен (» * «, » ? » и т.д.).
  • Перенаправление ввода/вывода команд.
  • Управление заданиями.

Кроме того, shell — это специализированный язык программирования, в котором есть переменные, конструкции while, if, for и т.д., функции и много чего еще. Он позволяет писать как несложные сценарии для автоматизации повседневных задач, так и довольно сложные программы (например, запуск и останов большинства Unix’ов производятся сценариями на языке shell).

Хотя работа непосредственно в командной строке (а не в оболочке типа NortonCommander или какой-нибудь оконной) на первый взгляд не столь удобна, она обеспечивает более удобный доступ к таким функциям, как перенаправление ввода/вывода и управление заданиями — оболочки типа Midnight Commander в этом случае будут только мешать.

Shell — это не одна конкретная программа. Исторически существует несколько подвидов оболочек; «генеалогическое древо» представлено на Рис.1.

Рис.1: семейство
интерпретаторов командной строки

Не вдаваясь в подробности истории (краткое описание можно найти в разделе 3.10 книги «Unix: универсальная среда программирования» Кернигана и Пайка), стоит лишь заметить, что csh и tcsh не в полной мере реализуют командный язык sh, а zsh, являясь самой последней разработкой, умеет все, что и любой другой подвид, и плюс много чего еще.

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

Изложение в данном разделе основано на zsh (которая и используется на практических занятиях), но большая часть описанного верно и для других оболочек.

Совет
Совет: чтобы узнать, какой используется shell, надо выполнить команду

Командная строка — Основы командной строки

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

Терминал

Терминалом называют программу, которая эмулирует поведение железного терминала, состоящего из клавиатуры и монитора. В простейшем случае — это просто окошко с командной строкой внутри:

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

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

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

Командная оболочка

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

Оболочка — это лишь средство для выполнения определенных задач, а не сама задача. Этим она отличается от многих других программ.

Внутри терминала пользователь передает системе строки:

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

Оболочка запускается внутри терминала и приглашает ко вводу команд:

Рассмотрим фрагмент кода подробнее. Мы видим:

  • Символ $ — он используется как разделитель
  • Слева от $ — настраиваемое сообщение для вывода, обычно это текущая директория
  • Справа от $ — команда, которую вводит пользователь

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

date Sun Aug 26 14:02:59 CEST 2018 █ 

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

# Комментарий █ 

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

  • Автоматическое завершение имен программ и файлов
  • Историю введенных команд
  • Возможность перемещаться по файловой системе
  • Удобные горячие клавиши
  • Поддержку скриптов

Далее в курсе мы раскроем многие из этих аспектов.

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

Отдельно скажем, что командная оболочка и терминал — не одно и то же. Терминал — это программа, которая запускает командную оболочку внутри себя:

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

Командную оболочку нередко называют реплом от английского REPL (Read-Eval-Print-Loop). Это сокращение отражает способ взаимодействия командной оболочки с пользователем:

  • Read — оболочка ждет ввода команды от пользователя
  • Eval — исполняет введенную команду
  • Print — выводит результат
  • Loop — возвращаемся к первому пункту

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

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

Чтобы вам было удобнее выполнять задания к урокам, в среде Хекслета сразу запущено два терминала. Терминалы доступны в нижних вкладках под именами Terminal 1 и Terminal 2.

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

Самостоятельная работа

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

Сначала нужно установить терминал. Установка зависит от вашей операционной системы:

  • Если вы используете Linux или MacOS, в вашей операционной системе уже есть установленный терминал. Можете использовать его или скачать более продвинутую версию — например, iTerm2 для MacOS и Tilix для Linux
  • Если вы работаете с ОС Windows, вам потребуется использовать WSL Далее убедитесь, что внутри терминала можно запустить bash-сессию. Откройте терминал и введите такой текст:

echo $SHELL /bin/bash # Это вывод команды, которую вы ввели выше 
Дополнительные материалы

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

  • Статья «Как учиться и справляться с негативными мыслями»
  • Статья «Ловушки обучения»
  • Статья «Сложные простые задачи по программированию»
  • Урок «Как эффективно учиться на Хекслете»
  • Вебинар «Как самостоятельно учиться»

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Unix2017b/Командная оболочка

Командная оболочка UNIX (англ. Unix shell, часто просто «шелл») — командный интерпретатор, используемый в операционных системах семейства Unix, в котором пользователь может либо давать команды операционной системе по отдельности, либо запускать скрипты, состоящие из списка команд.

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

  • 1 Виды
  • 2 История
    • 2.1 Thompson shell
    • 2.2 Bourne shell
    • 2.3 C shell
    • 3.1 Оболочки в Ubuntu
    • 3.2 Узнать текущую оболочку
    • 4.1 Терминалы
    • 4.2 Комбинации клавиш
    • 4.3 Получение справки
    • 4.4 man
      • 4.4.1 Разделы справки
      • 5.1 Шебанг (shebang)
      • 5.2 Переменная окружения PATH
      • 5.3 /usr/bin/env
      • 5.4 Создание сценариев командной оболочки (шелл-скриптов)
      • 6.1 Задача 1
      • 6.2 Задача 2

      Виды

      В первую очередь, под shell понимаются POSIX-совместимые оболочки, восходящие к Bourne shell (шелл Борна).

      Условно оболочки можно разделить их на четыре группы:

      • Клоны Bourne shell (bash, zsh)
      • C shell (csh, tcsh)
      • Базирующиеся на популярных языках программирования (psh, ipython, scsh)
      • Экзотические, специфические и все остальные

      История

      Thompson shell

      Первая оболочка Unix — Thompson shell, написанная Кеном Томпсоном в Bell Labs (1971–1975). По современным представлениям выглядит неразвитой, но уже поддерживала перенаправления ввода/вывода, метасимволы (wildcards) для имён файлов, простые управляющие выражения с if, goto (но они были сделаны через отдельные программы). Эта оболочка проектировалась под влиянием оболочки Multics, которая, в свою очередь, делалась на базе программы RUNCOM. Это название можно встретить на современных системах в суффиксе «rc» файлов конфигурации (например, .vimrc и .bashrc).

      Так, у Томпсона перенаправление выглядело следующим образом:

      command1 >command2>

      Такой синтаксис был затем заменён на привычный

      command1 | command2

      Затем появилась оболочка PWB shell (другое название — Mashey shell) (1975–1977). Там появились переменные (предшественники переменных окружения), доступ к ним через $, запуск скриптов, доработаны операторы if/then/else/endif, switch/breaksw/endsw и while/end/break/continue. Но она не стала особо популярной.

      Позже появились оболочки Bourne shell и C shell, которые оказали наибольшее влияние на развитие Unix-оболочек.

      Bourne shell

      Stephen R. Bourne

      Оболочка Bourne shell (часто называют sh по имени исполняемого файла) разработана с нуля Стивеном Борном (Stephen R. Bourne). Внедрена в ОС Unix в 1979 г (в седьмую версию ОС). Большая часть операторов была заимствована им из языка ALGOL 68. Например, наследие этого языка: перевёрнутое ключевое слово используется для завершения блока (iffi, caseesac). Приглашение командной строки отображается в виде доллара $.

      Оболочка Борна выполняла две основные задачи:

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

      Новая командная оболочка Bourne again shell (bash) разработана в 1987 году Брайаном Фоксом (Brian Fox) в рамках Free Software Foundation (Столлман). Фамилия Bourne (Борн) перекликается с английским словом born, означающим «родившийся», отсюда: рождённая-вновь-командная оболочка.

      Подавляющее большинство важных скриптов командного процессора Борна могут выполняться без изменения в bash.

      Командная оболочка Z shell (исполняемый файл zsh) — свободная современная sh-совместимая оболочка. Имеет ряд преимуществ перед bash, касающихся в основном работы в интерактивном режиме. Первая версия zsh была написана Паулем Фалстадом (Paul Falstad) в 1990 году.

      C shell

      Оболочка csh написана Биллом Джоем (Bill Joy) в университете Беркли в рамках проекта по реализации BSD Unix (1979). Билл также известен как автор текстового редактора vi.

      За основу для скриптового языка csh был взят, как понятно из названия, язык C. Т.к. на тот момент, в 1978 г., это был наиболее популярный язык программирования среди разработчиков и пользователей BSD UNIX.

      В настоящий момент более популярна свободная реализация csh — tcsh, или TENEX C Shell. Именно в tcsh когда-то впервые появилось автодополнение. Является оболочкой по умолчанию в FreeBSD.

      #!/bin/sh if [ $days -gt 365 ] then echo This is over a year. fi
      #!/bin/csh if ( $days > 365 ) then echo This is over a year. endif
      #!/bin/sh i=2 j=1 while [ $j -le 10 ] do echo '2 **' $j = $i i=`expr $i '*' 2` j=`expr $j + 1` done
      #!/bin/csh set i = 2 set j = 1 while ( $j = 10 ) echo '2 **' $j = $i @ i *= 2 @ j++ end

      Синтаксис csh на первый взгляд может показаться соблазнительным, потому что похож на C, но в общем использовать эту оболочку для написания скриптов не рекомендуется. Не хватает возможностей по работе с потоками (stdout и stderr) и поддержки функций. В самом интерпретаторе csh используется плохой примитивный парсер (в связи с тем, что в 70-е не была развита наука о компиляторах), из-за чего некоторые на вид корректные скрипты не работают так, как ожидается. Сообщения об ошибках парсинга очень неинформативные.

      Кроме недостатка функциональности, можно заметить, что количество книг, справочных ресурсов, вопросов на Stackoverflow и пр. для tcsh гораздо меньше, чем для bash.

      Современное состояние

      Традиционно в Unix-системах шелл Борна называется sh и, согласно FHS, лежит в /bin/sh. На настоящих системах это часто символическая или жёсткая ссылка на один из альтернативных шеллов:

      • ash (Almquist shell, оболочка Альмквиста);
      • bash (Bourne-again shell, «ещё-одна-командная-оболочка-Борна»);
      • dash (Debian Almquist shell);
      • ksh (Korn shell);
      • zsh (Z shell, современная, имеет ряд преимуществ перед bash касающихся в основном работы в интерактивном режиме);
      • BusyBox — современная микро-версия, предназначенные для встраиваемых систем;
      • .

      Стандарт POSIX специфицирует стандартную оболочку как строгое подмножество Korn shell, расширенной версии оригинальной Bourne shell.

      Bash — одна из наиболее популярных современных разновидностей командной оболочки. Особенно популярна в среде Linux, где она часто используется в качестве предустановленной командной оболочки.

      Оболочки в Ubuntu

      Начиная с версии Ubuntu 6.10 (октябрь 2006 г.), ссылка /bin/sh изменена с bash на dash. Это привело к неработоспособности многочисленных скриптов.

      bash остаётся оболочкой для входа в систему по умолчанию.

      Главная причина — эффективность. Оболочка dash более легковесна, при загрузке ОС выполняется большое количество скриптов, в которых возможности bash избыточны.

      sobols@sobols-VirtualBox:~$ ls /bin/*sh -l -rwxr-xr-x 1 root root 1017016 Крс 24 2014 /bin/bash -rwxr-xr-x 1 root root 121272 Лют 19 2014 /bin/dash lrwxrwxrwx 1 root root 4 Врс 19 2014 /bin/rbash -> bash lrwxrwxrwx 1 root root 9 Врс 14 09:36 /bin/sh -> /bin/dash lrwxrwxrwx 1 root root 7 Врс 19 2014 /bin/static-sh -> busybox

      Узнать текущую оболочку

      echo $0 echo $SHELL

      Работа в интерактивном режиме

      Терминалы

      Ядра UNIX-систем имеют общее понятие терминалов. Терминал предоставляет возможность приложениям отображать выходные данные и принимать входные данные через терминальное устройство. Процесс может иметь управляющий терминал — для приложения с текстовым режимом, так он взаимодействует с пользователем.

      Терминалы могут быть:

      • аппаратными терминалами («tty», от «телетайп»),
      • псевдотерминалами («pty»).

      Аппаратные терминалы подключаются через некоторый интерфейс, такой как последовательный порт (ttyS0, . ) или USB (ttyUSB0, . ), или через экран ПК и клавиатуру (tty1, . ). Псевдотерминалы предоставляются терминальным эмулятором, который является приложением. Файлы в каталоге /dev/pts являются псевдотерминалами.

      Некоторые типы псевдотерминалов:

      • Приложения GUI, такие как xterm, gnome-terminal, konsole, . преобразуют клавиатуру и события мыши в текстовый ввод и вывод изображения графически некоторым шрифтом.
      • Мультиплексорные приложения, такие как screen и tmux, передают ввод и вывод на другой терминал, чтобы отделить приложения от фактического терминала.
      • Удаленные приложения оболочки, такие как sshd, telnetd, rlogind, . передают ввод и вывод между удалённым терминалом на клиенте и pty на сервере.

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

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

      Чтобы поэкспериментировать, запустите команду tty в терминале, чтобы узнать, какое терминальное устройство используется. Скажем, это /dev/pts/42. В шелле в другом терминале запустите echo

      echo hello> /dev/pts/42

      Приветствие hello будет отображаться на другом терминале. Теперь запустите

      cat /dev/pts/42

      и введите в другой терминал. Чтобы убить эту команду, нажмите Ctrl+C.

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

      При нажатии клавиш Ctrl+Alt+F1, Ctrl+Alt+F2, из графической оболочки Linux-дистрибутива можно попасть в текстовый режим в терминалы tty1, tty2, . Для возврата обратно в графический режим обычно можно нажать Ctrl+Alt+F7.

      Комбинации клавиш

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

      • Tab — автодополнение.
      • Стрелки вверх-вниз (также Ctrl+P и Ctrl+N) — история команд.
      • Home и End (также Ctrl+A и Ctrl+E) — переход в начало/конец строки.
      • Alt+B и Alt+F (также Ctrl и стрелки влево-вправо) — переход по словам назад/вперёд.
      • Ctrl+L — очистить экран.
      • Ctrl+R — поиск по истории.

      Получение справки

      man

      man (от англ. manual — руководство) — команда UNIX, предназначенная для форматирования и вывода справочных страниц. Поставляется почти со всеми UNIX-подобными дистрибутивами. Каждая страница справки является самостоятельным документом и пишется разработчиками соответствующего программного обеспечения.

      Чтобы вывести справочное руководство по какой-либо команде (или программе, предусматривающей возможность запуска из терминала), можно в консоли ввести:

      man command_name

      Например, чтобы посмотреть справку по команде ls, нужно ввести man ls.

      Для навигации в справочной системе man можно использовать клавиши ↑ и ↓ для построчного перехода, PgUp и PgDn для постраничного перехода вверх и вниз соответственно.

      При просмотре больших страниц удобно воспользоваться поиском, для чего следует нажать /, затем набрать строку поиска (и слеш, и строка поиска отобразятся в нижней части экрана) и нажать Enter. Обратным поиском (снизу вверх) можно воспользоваться, нажав кнопку ?. При этом подсветятся все совпадения с заданным регулярным выражением, и экран прокрутится до первого из них. Для перехода к следующему подсвеченному вхождению нужно нажать n (Next — следующий), либо оставить строку поиска пустой (/, затем Enter). Для показа предыдущего совпадения надо также использовать вопросительный знак или же нажимать N (заглавную).

      Для получения краткой справки по командам и горячим клавишам справочной системы нужно нажать H (Help — помощь).

      Для выхода из справочной системы используется клавиша Q (Quit — выход).

      Для получения детальной инструкции по использованию команды используется конструкция

      man man
      Разделы справки
      Раздел Краткое описание
      1 Прикладные программы и команды оболочки
      2 Системные вызовы ядра (функции языка C)
      3 Библиотечные вызовы (функции различных библиотек, установленных в систему)
      4 Специальные файлы (находящиеся обычно в каталоге /dev)
      5 Форматы файлов и соглашения
      6 Игры
      7 Различные описания, соглашения и прочее
      8 Команды администрирования системы, которые обычно запускаются от имени суперпользователя
      9 Ядро операционной системы (нестандартный раздел)

      Номер раздела в команде man указывается вторым аргументом, перед названием справочной страницы. Если номер раздела опущен, то поиск справочной страницы ведётся по всем разделам по порядку.

      man passwd #раздел 1 man 1 passwd #раздел 1 man 5 passwd #раздел 5

      info

      Альтернатива для man от проекта GNU.

      Запуск программ

      • бинарные исполняемые файлы (в формате ELF и пр.);
      • текстовые программы (скрипты) на интерпретируемых языках.

      И те, и те файлы в UNIX-системах имеют выставленные биты права на выполнение. Право на выполнение (x) означает, что вы можете загрузить файл в память и попытаться запустить его на выполнение как исполняемую программу. Загрузчик по первым байтам понимает, как запускать этот исполняемый файл.

      Шебанг (shebang)

      Последовательность из двух символов: решётки и восклицательного знака (#!) в начале файла скрипта.

      Когда скрипт с шебангом выполняется как программа в UNIX-подобных операционных системах, загрузчик программ рассматривает остаток строки после шебанга как имя файла программы-интерпретатора. Загрузчик запускает эту программу и передаёт ей в качестве параметра имя файла скрипта с шебангом.

      #!interpreter [optional-arg]

      interpreter должен быть абсолютным путём.

      Пример: в файле some/path/to/foo записано

      #!/bin/sh -x

      и он запускается как

      some/path/to/foo bar baz

      Это то же самое, что запустить

      /bin/sh -x some/path/to/foo bar baz

      Вопрос: что будет, если запустить

      #!/bin/cat Hello world!

      Ответ: напечатаются обе строки.

      Переменная окружения PATH

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

      На POSIX и Unix-подобных операционных системах переменная PATH задана как одно или несколько имён каталогов, разделённых двоеточиями (:).

      echo $PATH

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

      Since is a separator in this context, directory names that might be used in PATH should not include a character.

      В основном в переменную PATH входят каталоги /bin, /usr/bin и /usr/local/bin.

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

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

      /usr/bin/env

      Для переносимости, чтобы не указывать полный путь к интерпретатору, в шебанг прописывают программу /usr/bin/env. Например,

      /usr/bin/env python

      запустит первый python, который будет найден в PATH.

      Пусть есть следующий скрипт на Python:

      #!/usr/bin/env python import sys print sys.executable
      sobols@sobols-VirtualBox:~/unix/path$ ./main.py /usr/bin/python sobols@sobols-VirtualBox:~/unix/path$ virtualenv venv Running virtualenv with interpreter /usr/bin/python2 New python executable in /home/sobols/unix/path/venv/bin/python2 Also creating executable in /home/sobols/unix/path/venv/bin/python Installing setuptools, pkg_resources, pip, wheel. done. sobols@sobols-VirtualBox:~/unix/path$ source ./venv/bin/activate (venv) sobols@sobols-VirtualBox:~/unix/path$ ./main.py /home/sobols/unix/path/venv/bin/python

      Создание сценариев командной оболочки (шелл-скриптов)

      Сценарий представляет собой обычный текстовый файл, редактируемый в текстовом редакторе. Можно выбрать по вкусу

      • nano / mcedit (mc F4) / evim
      • gedit
      • Sublime Text
      • .

      Расширение файла значения не имеет. Часто используется .sh.

      chmod +x script.sh

      Практические задания

      Задача 1

      Любым способом создайте файл, в имени которого присутствует перевод строки. Проверьте, как выводит такое имя команда ls.

      Задача 2

      Переименуйте файл file.txt в -file-.txt.

      1 что такое язык оболочки командной строки

      Язык оболочки командной строки (shell language) в Windows реализован в виде командных (или пакетных) файлов. Командный файл в Windows — это обычный текстовый файл с расширением bat или cmd, в котором записаны допустимые команды операционной системы (как внешние, так и внутренние), а также некоторые дополнительные инструкции и ключевые слова, придающие командным файлам некоторое сходство с алгоритмическими языками программирования. Например, если записать в файл deltmp.bat следующие команды:

      C:\ CD %TEMP% DEL /F *.tmp

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

      Вывод сообщений и дублирование команд

      По умолчанию команды пакетного файла перед исполнением выводятся на экран, что выглядит не очень эстетично. С помощью команды ECHO OFF можно отключить дублирование команд, идущих после нее (сама команда ECHO OFF при этом все же дублируется). Например,

      REM Следующие две команды будут дублироваться на экране … DIR C:\ ECHO OFF REM А остальные уже не будут DIR D:\

      Для восстановления режима дублирования используется команда ECHO ON . Кроме этого, можно отключить дублирование любой отдельной строки в командном файле, написав в начале этой строки символ @ , например:

      ECHO ON REM Команда DIR C:\ дублируется на экране DIR C:\ REM А команда DIR D:\ — нет @DIR D:\

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

      @ECHO OFF

      то это решит все проблемы с дублированием команд.

      В пакетном файле можно выводить на экран строки с сообщениями. Делается это с помощью команды

      ECHO сообщение
      @ECHO OFF ECHO Привет! Команда ECHO. (точка должна следовать непосредственно за словом "ECHO") выводит на экран пустую строку. Например, @ECHO OFF ECHO Привет! ECHO. ECHO Пока!

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

      Используя механизм перенаправления ввода/вывода (символы > и >>), можно направить сообщения, выводимые командой ECHO , в определенный текстовый файл. Например:

      @ECHO OFF ECHO Привет! > hi.txt ECHO Пока! >> hi.txt С помощью такого метода можно, скажем, заполнять файлы-протоколы с отчетом о произведенных действиях. Например: @ECHO OFF REM Попытка копирования XCOPY C:\PROGRAMS D:\PROGRAMS /s REM Добавление сообщения в файл report.txt в случае REM удачного завершения копирования IF NOT ERRORLEVEL 1 ECHO Успешное копирование >> report.txt
      Использование параметров командной строки

      При запуске пакетных файлов в командной строке можно указывать произвольное число параметров, значения которых можно использовать внутри файла. Это позволяет, например, применять один и тот же командный файл для выполнения команд с различными параметрами.

      Для доступа из командного файла к параметрам командной строки применяются символы %0, %1, …, %9 или %* . При этом вместо %0 подставляется имя выполняемого пакетного файла, вместо %1, %2, …, %9 — значения первых девяти параметров командной строки соответственно, а вместо %* — все аргументы. Если в командной строке при вызове пакетного файла задано меньше девяти параметров, то «лишние» переменные из %1 – %9 замещаются пустыми строками. Рассмотрим следующий пример. Пусть имеется командный файл copier.bat следующего содержания:

      @ECHO OFF CLS ECHO Файл %0 копирует каталог %1 в %2 XCOPY %1 %2 /S

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

      copier.bat C:\Programs D:\Backup

      то на экран выведется сообщение

      Файл copier.bat копирует каталог C:\Programs в D:\Backup

      и произойдет копирование каталога C:\Programs со всеми его подкаталогами в D:\Backup.

      При необходимости можно использовать более девяти параметров командной строки. Это достигается с помощью команды SHIFT , которая изменяет значения замещаемых параметров с %0 по %9 , копируя каждый параметр в предыдущий, то есть значение %1 копируется в %0 , значение %2 – в %1 и т.д. Замещаемому параметру %9 присваивается значение параметра, следующего в командной строке за старым значением %9 . Если же такой параметр не задан, то новое значение %9 — пустая строка.

      Рассмотрим пример. Пусть командный файл my.bat вызван из командной строки следующим образом:

      my.bat p1 p2 p3

      Тогда %0=my.bat, %1=p1, %2=p2, %3=p3 , параметры %4 – %9 являются пустыми строками. После выполнения команды SHIFT значения замещаемых параметров изменятся следующим образом: %0=p1, %1=p2, %2=p3 , параметры %3 – %9 – пустые строки.

      При включении расширенной обработки команд SHIFT поддерживает ключ /n , задающий начало сдвига параметров с номера n , где n может быть числом от 0 до 9.

      Например, в следующей команде:

      SHIFT /2

      параметр %2 заменяется на %3 , %3 на %4 и т.д., а параметры %0 и %1 остаются без изменений.

      Команда, обратная SHIFT (обратный сдвиг), отсутствует. После выполнения SHIFT уже нельзя восстановить параметр (%0) , который был первым перед сдвигом. Если в командной строке задано больше десяти параметров, то команду SHIFT можно использовать несколько раз.

      В командных файлах имеются некоторые возможности синтаксического анализа заменяемых параметров. Для параметра с номером n (%n) допустимы синтаксические конструкции (операторы), представленные в табл. 3.1.

      Таблица 3.1. Операторы для заменяемых параметров

      Операторы Описание
      %~Fn Переменная %n расширяется до полного имени файла
      %~Dn Из переменной %n выделяется только имя диска
      %~Pn Из переменной %n выделяется только путь к файлу
      %~Nn Из переменной %n выделяется только имя файла
      %~Xn Из переменной %n выделяется расширение имени файла
      %~Sn Значение операторов N и X для переменной %n изменяется так, что они работают с кратким именем файла
      %~$PATH:n Проводится поиск по каталогам, заданным в переменной среды PATH , и переменная %n заменяется на полное имя первого найденного файла. Если переменная PATH не определена или в результате поиска не найден ни один файл, эта конструкция заменяется на пустую строку. Естественно, здесь переменную PATH можно заменить на любое другое допустимое значение

      Данные синтаксические конструкции можно объединять друг с другом, например:

      %~DPn — из переменной %n выделяется имя диска и путь,

      %~NXn — из переменной %n выделяется имя файла и расширение.

      Рассмотрим следующий пример. Пусть мы находимся в каталоге C:\TEXT и запускаем пакетный файл с параметром Рассказ.doc ( %1=Рассказ.doc ). Тогда применение операторов, описанных в табл. 3.1, к параметру %1 даст следующие результаты:

      %~F1=C:\TEXT\Рассказ.doc %~D1=C: %~P1=\TEXT\ %~N1=Рассказ %~X1=.doc %~DP1=C:\TEXT\ %~NX1=Рассказ.doc
      Работа с переменными среды

      Внутри командных файлов можно работать с так называемыми переменными среды (или переменными окружения), каждая из которых хранится в оперативной памяти, имеет свое уникальное имя, а ее значением является строка. Стандартные переменные среды автоматически инициализируются в процессе загрузки операционной системы. Такими переменными являются, например, WINDIR, которая определяет расположение каталога Windows, TEMP, которая определяет путь к каталогу для хранения временных файлов Windows или PATH, в которой хранится системный путь (путь поиска), то есть список каталогов, в которых система должна искать выполняемые файлы или файлы совместного доступа (например, динамические библиотеки). Кроме того, в командных файлах с помощью команды SET можно объявлять собственные переменные среды.

      Получение значения переменной

      Для получения значения определенной переменной среды нужно имя этой переменной заключить в символы % . Например:

      @ECHO OFF CLS REM Создание переменной MyVar SET MyVar=Привет REM Изменение переменной SET MyVar=%MyVar%! ECHO Значение переменной MyVar: %MyVar% REM Удаление переменной MyVar SET MyVar= ECHO Значение переменной WinDir: %WinDir%

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

      Значение переменной MyVar: Привет!Значение переменной WinDir: C:\WINDOWS
      Преобразования переменных как строк

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

      SET A=Раз SET B=Два SET C=%A%%B%

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

      SET A=Раз SET B=Два SET C=A+B ECHO Переменная C=%C% SET D=%A%+%B% ECHO Переменная D=%D%

      на экран выведутся две строки:

      Переменная C=A+BПеременная D=Раз+Два

      Во-вторых, из переменной среды можно выделять подстроки с помощью конструкции %имя_переменной:~n1,n2%, где число n1 определяет смещение (количество пропускаемых символов) от начала (если n1 положительно) или от конца (если n1 отрицательно) соответствующей переменной среды, а число n2 – количество выделяемых символов (если n2 положительно) или количество последних символов в переменной, которые не войдут в выделяемую подстроку (если n2 отрицательно). Если указан только один отрицательный параметр -n , то будут извлечены последние n символов. Например, если в переменной хранится строка «21.09.2007» (символьное представление текущая дата при определенных региональных настройках), то после выполнения следующих команд

      SET dd1=%DATE:~0,2% SET dd2=%DATE:~0,-8% SET mm=%DATE:~-7,2% SET yyyy=%DATE:~-4%

      новые переменные будут иметь такие значения: %dd1%=21, %dd2%=21, %mm%=09, %yyyy%=2007.

      В-третьих, можно выполнять процедуру замены подстрок с помощью конструкции %имя_переменной:s1=s2% (в результате будет возвращена строка, в которой каждое вхождение подстроки s1 в соответствующей переменной среды заменено на s2 ). Например, после выполнения команд

      SET a=123456 SET b=%a:23=99%

      в переменной b будет храниться строка «199456» . Если параметр s2 не указан, то подстрока s1 будет удалена из выводимой строки, т.е. после выполнения команды

      SET a=123456 SET b=%a:23=%

      в переменной b будет храниться строка «1456» .

      Операции с переменными как с числами

      При включенной расширенной обработке команд (этот режим в Windows XP используется по умолчанию) имеется возможность рассматривать значения переменных среды как числа и производить с ними арифметические вычисления. Для этого используется команда SET с ключом /A . Приведем пример пакетного файла add.bat, складывающего два числа, заданных в качестве параметров командной строки, и выводящего полученную сумму на экран:

      @ECHO OFF REM В переменной M будет храниться сумма SET /A M=%1+%2 ECHO Сумма %1 и %2 равна %M% REM Удалим переменную M SET M=
      Локальные изменения переменных

      Все изменения, производимые с помощью команды SET над переменными среды в командном файле, сохраняются и после завершения работы этого файла, но действуют только внутри текущего командного окна. Также имеется возможность локализовать изменения переменных среды внутри пакетного файла, то есть автоматически восстанавливать значения всех переменных в том виде, в каком они были до начала запуска этого файла. Для этого используются две команды: SETLOCAL и ENDLOCAL . Команда SETLOCAL определяет начало области локальных установок переменных среды. Другими словами, изменения среды, внесенные после выполнения SETLOCAL , будут являться локальными относительно текущего пакетного файла. Каждая команда SETLOCAL должна иметь соответствующую команду ENDLOCAL для восстановления прежних значений переменных среды. Изменения среды, внесенные после выполнения команды ENDLOCAL , уже не являются локальными относительно текущего пакетного файла; их прежние значения не будут восстановлены по завершении выполнения этого файла.

      Связывание времени выполнения для переменных

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

      SET a=1 ECHO a=%a% SET a=2 ECHO a=%a%

      и командный файл 2.bat:

      SET a=1 ECHO a=%a% (SET a=2 ECHO a=%a% )

      Казалось бы, результат выполнения этих двух файлов должен быть одинаковым: на экран выведутся две строки: «a=1» и «a=2» . На самом же деле таким образом сработает только файл 1.bat, а файл 2.bat два раза выведет строку «a=1»!

      Данную ошибку можно обойти, если для получения значения переменной вместо знаков процента (%) использовать восклицательный знак (!) и предварительно включить режим связывания времени выполнения командой SETLOCAL ENABLEDELAYEDEXPANSION . Таким образом, для корректной работы файл 2.bat должен иметь следующий вид:

      SETLOCAL ENABLEDELAYEDEXPANSION SET a=1 ECHO a=%a% (SET a=2 ECHO a=!a! )
      Приостановка выполнения командных файлов

      Для того, чтобы вручную прервать выполнение запущенного bat-файла, нужно нажать клавиши + или +. Однако часто бывает необходимо программно приостановить выполнение командного файла в определенной строке с выдачей запроса на нажатие любой клавиши. Это делается с помощью команды PAUSE. Перед запуском этой команды полезно с помощью команды ECHO информировать пользователя о действиях, которые он должен произвести. Например:

      ECHO Вставьте дискету в дисковод A: и нажмите любую клавишу PAUSE

      Команду PAUSE обязательно нужно использовать при выполнении потенциально опасных действий (удаление файлов, форматирование дисков и т.п.). Например,

      ECHO Сейчас будут удалены все файлы в C:\Мои документы! ECHO Для отмены нажмите Ctrl-C PAUSE DEL "C:\Мои документы\*.*"
      Вызов внешних командных файлов

      Из одного командного файла можно вызвать другой, просто указав его имя. Например:

      @ECHO OFF CLS REM Вывод списка log-файлов DIR C:\*.log REM Передача выполнения файлу f.bat f.bat COPY A:\*.* C:\ PAUSE

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

      COPY A:\*.* C:\

      (и все следующие за ней команды) никогда не будет выполнена.

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

      CALL файл Например: @ECHO OFF CLS REM Вывод списка log-файлов DIR C:\*.log REM Передача выполнения файлу f.bat CALL f.bat COPY A:\*.* C:\ PAUSE

      В этом случае после завершения работы файла f.bat управление вернется в первоначальный файл на строку, следующую за командой CALL (в нашем примере это команда COPY A:\*.* C:\ ).

      Операторы перехода

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

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

      @ECHO OFF COPY %1 %2 GOTO Label1 ECHO Эта строка никогда не выполнится :Label1 REM Продолжение выполнения DIR %2 После того, как в этом файле мы доходим до команды GOTO Label1 его выполнение продолжается со строки REM Продолжение выполнения

      В команде перехода внутри файла GOTO можно задавать в качестве метки перехода строку :EOF , которая передает управление в конец текущего пакетного файла (это позволяет легко выйти из пакетного файла без определения каких-либо меток в самом его конце).

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

      CALL :метка аргументы

      При вызове такой команды создается новый контекст текущего пакетного файла с заданными аргументами, и управление передается на инструкцию, расположенную сразу после метки. Для выхода из такого пакетного файла необходимо два раза достичь его конца. Первый выход возвращает управление на инструкцию, расположенную сразу после строки CALL , а второй выход завершает выполнение пакетного файла. Например, если запустить с параметром «Копия-1» командный файл следующего содержания:

      @ECHO OFF ECHO %1 CALL :2 Копия-2 :2 ECHO %1

      то на экран выведутся три строки:

      Копия-1 Копия-2 Копия-1

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

      Операторы условия

      С помощью команды IF … ELSE (ключевое слово ELSE может отсутствовать) в пакетных файлах можно выполнять обработку условий нескольких типов. При этом если заданное после IF условие принимает истинное значение, система выполняет следующую за условием команду (или несколько команд, заключенных в круглые скобки), в противном случае выполняется команда (или несколько команд в скобках), следующие за ключевым словом ELSE .

      Проверка значения переменной

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

      IF [NOT] строка1==строка2 команда1 [ELSE команда2]

      (квадратные скобки указывают на необязательность заключенных в них параметров) или

      IF [/I] [NOT] строка1 оператор_сравнения строка2 команда

      Рассмотрим сначала первый вариант. Условие строка1==строка2 (здесь необходимо писать именно два знака равенства) считается истинным при точном совпадении обеих строк. Параметр NOT указывает на то, что заданная команда выполняется лишь в том случае, когда сравниваемые строки не совпадают.

      Строки могут быть литеральными или представлять собой значения переменных (например, %1 или %TEMP% ). Кавычки для литеральных строк не требуются. Например,

      IF %1==%2 ECHO Параметры совпадают! IF %1==Петя ECHO Привет, Петя!

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

      IF %MyVar%==C:\ ECHO Ура.

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

      IF -%MyVar%==-C:\ ECHO Ура.

      С помощью команд IF и SHIFT можно в цикле обрабатывать все параметры командной строки файла, даже не зная заранее их количества. Например, следующий командный файл (назовем его primer.bat) выводит на экран имя запускаемого файла и все параметры командной строки:

      @ECHO OFF ECHO Выполняется файл: %0 ECHO. ECHO Файл запущен со следующими параметрами. REM Начало цикла :BegLoop IF -%1==- GOTO ExitLoop ECHO %1 REM Сдвиг параметров SHIFT REM Переход на начало цикла GOTO BegLoop :ExitLoop REM Выход из цикла ECHO. ECHO Все.

      Если запустить primer.bat с четырьмя параметрами:

      primer.bat А Б В Г

      то в результате выполнения на экран выведется следующая информация:

      Выполняется файл: primer.bat Файл запущен со следующими параметрами: А Б В Г Все.

      Рассмотрим теперь оператор IF в следующем виде:

      IF [/I] строка1 оператор_сравнения строка2 команда

      Синтаксис и значение операторов сравнения представлены в табл. 3.2.

      Таблица 3.2. Операторы сравнения в IF

      Оператор Значение
      EQL Равно
      NEQ Не равно
      LSS Меньше
      LEQ Меньше или равно
      GTR Больше
      GEQ Больше или равно

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

      @ECHO OFF CLS IF -%1 EQL –Вася ECHO Привет, Вася! IF -%1 NEQ –Вася ECHO Привет, но Вы не Вася!

      Ключ /I , если он указан, задает сравнение текстовых строк без учета регистра. Ключ /I можно также использовать и в форме строка1==строка2 команды IF . Например, условие

      IF /I DOS==dos …
      Проверка существования заданного файла

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

      IF [NOT] EXIST файл команда1 [ELSE команда2]

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

      @ECHO OFF IF -%1==- GOTO NoFileSpecified IF NOT EXIST %1 GOTO FileNotExist REM Вывод сообщения о найденном файле ECHO Файл '%1' успешно найден. GOTO :EOF :NoFileSpecified REM Файл запущен без параметров ECHO В командной строке не указано имя файла. GOTO :EOF :FileNotExist REM Параметр командной строки задан, но файл не найден ECHO Файл '%1' не найден.
      Проверка наличия переменной среды

      Аналогично файлам команда IF позволяет проверить наличие в системе определенной переменной среды:

      IF DEFINED переменная команда1 [ELSE команда2]

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

      @ECHO OFF CLS IF DEFINED MyVar GOTO :VarExists ECHO Переменная MyVar не определена GOTO :EOF :VarExists ECHO Переменная MyVar определена, ECHO ее значение равно %MyVar%
      Проверка кода завершения предыдущей команды

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

      IF [NOT] ERRORLEVEL число команда1 [ELSE команда2]

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

      Составим, например, командный файл, который бы копировал файл my.txt на диск C: без вывода на экран сообщений о копировании, а в случае возникновения какой-либо ошибки выдавал предупреждение:

      @ECHO OFF XCOPY my.txt C:\ > NUL REM Проверка кода завершения копирования IF ERRORLEVEL 1 GOTO ErrOccurred ECHO Копирование выполнено без ошибок. GOTO :EOF :ErrOccurred ECHO При выполнении команды XCOPY возникла ошибка!

      В операторе IF ERRORLEVEL … можно также применять операторы сравнения чисел, приведенные в табл. 3.2. Например:

      IF ERRORLEVEL LEQ 1 GOTO Case1

      Иногда более удобным для работы с кодами завершения программ может оказаться использование переменной %ERRORLEVEL% . (строковое представление текущего значения кода ошибки ERRORLEVEL ).

      Проверка версии реализации расширенной обработки команд

      Наконец, для определения внутреннего номера версии текущей реализации расширенной обработки команд применяется оператор IF в следующем виде:

      IF CMDEXTVERSION число команда1 [ELSE команда2]

      Здесь условие CMDEXTVERSION применяется подобно условию ERRORLEVEL , но число сравнивается с вышеупомянутым внутренним номером версии. Первая версия имеет номер 1. Номер версии будет увеличиваться на единицу при каждом добавлении существенных возможностей расширенной обработки команд. Если расширенная обработка команд отключена, условие CMDEXTVERSION никогда не бывает истинно.

      Организация циклов
      • выполнение заданной команды для всех элементов указанного множества;
      • выполнение заданной команды для всех подходящих имен файлов;
      • выполнение заданной команды для всех подходящих имен каталогов;
      • выполнение заданной команды для определенного каталога, а также всех его подкаталогов;
      • получение последовательности чисел с заданными началом, концом и шагом приращения;
      • чтение и обработка строк из текстового файла;
      • обработка строк вывода определенной команды.
      Цикл FOR … IN … DO …

      Самый простой вариант синтаксиса команды FOR для командных файлов имеет следующий вид:

      FOR %%переменная IN (множество) DO команда [параметры]

      Перед названием переменной должны стоять именно два знака процента (%%) , а не один, как это было при использовании команды FOR непосредственно из командной строки.

      Сразу приведем пример. Если в командном файле заданы строки

      @ECHO OFF FOR %%i IN (Раз,Два,Три) DO ECHO %%i

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

      Раз Два Три

      Параметр множество в команде FOR задает одну или более текстовых строк, разделенных запятыми, которые вы хотите обработать с помощью заданной команды. Скобки здесь обязательны. Параметр команда [параметры] задает команду, выполняемую для каждого элемента множества, при этом вложенность команд FOR на одной строке не допускается. Если в строке, входящей во множество, используется запятая, то значение этой строки нужно заключить в кавычки. Например, в результате выполнения файла с командами

      @ECHO OFF FOR %%i IN ("Раз,Два",Три) DO ECHO %%i

      на экран будет выведено

      Раз,Два Три

      Параметр %%переменная представляет подставляемую переменную (счетчик цикла), причем здесь могут использоваться только имена переменных, состоящие из одной буквы. При выполнении команда FOR заменяет подставляемую переменную текстом каждой строки в заданном множестве, пока команда, стоящая после ключевого слова DO , не обработает все такие строки.

      Чтобы избежать путаницы с параметрами командного файла %0 — %9 , для переменных следует использовать любые символы кроме 0 – 9 .

      Параметр множество в команде FOR может также представлять одну или несколько групп файлов. Например, чтобы вывести в файл список всех файлов с расширениями txt и prn, находящихся в каталоге C:\TEXT, без использования команды DIR , можно использовать командный файл следующего содержания:

      @ECHO OFF FOR %%f IN (C:\TEXT\*.txt C:\TEXT\*.prn) DO ECHO %%f >> list.txt

      При таком использовании команды FOR процесс обработки продолжается, пока не обработаются все файлы (или группы файлов), указанные во множестве.

      Цикл FOR /D … IN … DO …

      Следующий вариант команды FOR реализуется с помощью ключа /D:

      FOR /D %переменная IN (набор) DO команда [параметры]

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

      @ECHO OFF CLS FOR /D %%f IN (C:\*.*) DO ECHO %%f

      мы получим список всех каталогов на диске C:, например:

      C:\Arc C:\CYR C:\MSCAN C:\NC C:\Program Files C:\TEMP C:\TeX C:\WINNT
      Цикл FOR /R … IN … DO …

      С помощью ключа /R можно задать рекурсию в команде: FOR :

      FOR /R [[диск:]путь] %переменная IN (набор) DO команда [параметры]

      В этом случае заданная команда выполняется для каталога [диск:]путь , а также для всех подкаталогов этого пути. Если после ключа R не указано имя каталога, то выполнение команды начинается с текущего каталога. Например, для распечатки всех файлов с расширением txt в текущем каталоге и всех его подкаталогах можно использовать следующий пакетный файл:

      @ECHO OFF CLS FOR /R %%f IN (*.txt) DO PRINT %%f

      Если вместо набора указана только точка (.) , то команда проверяет все подкаталоги текущего каталога. Например, если мы находимся в каталоге C:\TEXT с двумя подкаталогами BOOKS и ARTICLES, то в результате выполнения файла:

      @ECHO OFF CLS FOR /R %%f IN (.) DO ECHO %%f на экран выведутся три строки: C:\TEXT\. C:\TEXT\BOOKS\. C:\TEXT\ARTICLES\.
      Цикл FOR /L … IN … DO …

      Ключ /L позволяет реализовать с помощью команды FOR арифметический цикл, в этом случае синтаксис имеет следующий: вид:

      FOR /L %переменная IN (начало,шаг,конец) DO команда [параметры]

      Здесь заданная после ключевого слова IN тройка (начало,шаг,конец) раскрывается в последовательность чисел с заданными началом, концом и шагом приращения. Так, набор (1,1,5) раскрывается в (1 2 3 4 5), а набор (5,-1,1) заменяется на (5 4 3 2 1). Например, в результате выполнения следующего командного файла:

      @ECHO OFF CLS FOR /L %%f IN (1,1,5) DO ECHO %%f

      переменная цикла %%f пробежит значения от 1 до 5, и на экране напечатаются пять чисел:

      1 2 3 4 5

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

      @ECHO OFF CLS FOR /L %%f IN (1,1,5) DO CALL :2 %%f GOTO :EOF :2 SET /A M=10*%1 ECHO 10*%1=%M%

      В третьей строке в цикле происходит вызов нового контекста файла my.bat с текущим значением переменной цикла %%f в качестве параметра командной строки, причем управление передается на метку :2 (см. описание CALL в разделе «Изменения в командах перехода»). В шестой строке переменная цикла умножается на десять, и результат записывается в переменную M . Таким образом, в результате выполнения этого файла выведется следующая информация:

      10*1=10 10*2=20 10*3=30 10*4=40 10*5=50
      Цикл FOR /F … IN … DO …

      Самые мощные возможности (и одновременно самый запутанный синтаксис) имеет команда: FOR с ключом /F :

      FOR /F ["ключи"] %переменная IN (набор) DO команда [параметры]

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

      По умолчаниюключ /F выделяет из каждой строки файла первое слово, очищенное от окружающих его пробелов. Пустые строки в файле пропускаются. Необязательный параметр «ключи» служит для переопределения заданных по умолчанию правил обработки строк. Ключи представляют собой заключенную в кавычки строку, содержащую приведенные в табл. 3.3 ключевые слова:

      Таблица 3.3. Ключи в команде FOR /F

      Ключ Описание
      EOL=C Определение символа комментариев в начале строки (допускается задание только одного символа)
      SKIP=N Число пропускаемых при обработке строк в начале файла
      DELIMS=XXX Определение набора разделителей для замены заданных по умолчанию пробела и знака табуляции
      TOKENS=X,Y,M-N Определение номеров подстрок, выделяемых из каждой строки файла и передаваемых для выполнения в тело цикла

      При использовании ключа TOKENS=X,Y,M-N создаются дополнительные переменные. Формат M-N представляет собой диапазон подстрок с номерами от M до N . Если последний символ в строке TOKENS= является звездочкой, то создается дополнительная переменная, значением которой будет весь текст, оставшийся в строке после обработки последней подстроки.

      Разберем применение этой команды на примере пакетного файла parser.bat, который производит разбор файла myfile.txt:

      @ECHO OFF IF NOT EXIST myfile.txt GOTO :NoFile FOR /F "EOL=; TOKENS=2,3* DELIMS=, " %%i IN (myfile.txt) DO @ECHO %%i %%j %%k GOTO :EOF :NoFile ECHO Не найден файл myfile.txt!

      Здесь во второй строке производится проверка наличия файла myfile.txt; в случае отсутствия этого файла выводится предупреждающее сообщение. Команда FOR в третьей строке обрабатывает файл myfile.txt следующим образом:

      Пропускаются все строки, которые начинаются с символа точки с запятой ( EOL=; ).

      Вторая и третья подстроки из каждой строки передаются в тело цикла, причем подстроки разделяются пробелами (по умолчанию) и/или запятыми ( DELIMS=, ).

      В теле цикла переменная %%i используется для второй подстроки, %%j — для третьей, а %%k получает все оставшиеся подстроки после третьей.

      В нашем примере переменная %%i явно описана в инструкции FOR , а переменные %%j и %%k описываются неявно с помощью ключа TOKENS= . Например, если в файле myfile.txt были записаны следующие три строки:

      ААА ББББ ВВВВ,ГГГГГ ДДДД ЕЕЕЕЕ,ЖЖЖЖ ЗЗЗЗ ;КККК ЛЛЛЛЛ МММММ

      то в результате выполнения пакетного файла parser.bat на экран выведется следующее:

      ББББ ВВВВ ГГГГГ ДДДД ЖЖЖЖ ЗЗЗЗ

      Ключ TOKENS= позволяет извлечь из одной строки файла до 26 подстрок, поэтому запрещено использовать имена переменных, начинающиеся не с букв английского алфавита (a–z). Следует помнить, что имена переменных FOR являются глобальными, поэтому одновременно не может быть активно более 26 переменных.

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

      @ECHO OFF FOR /F "EOL=; TOKENS=2,3* DELIMS=, " %%i IN ("ААА ББББ ВВВВ,ГГГГГ ДДДД") DO @ECHO %%i %%j %%k

      при своем выполнении напечатает

      ББББ ВВВВ ГГГГГ ДДДД

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

      @ECHO OFF SET M=ААА ББББ ВВВВ,ГГГГГ ДДДД FOR /F "EOL=; TOKENS=2,3* DELIMS=, " %%i IN ("%M%") DO @ECHO %%i %%j %%k

      Наконец, команда FOR /F позволяет обработать строку вывода другой команды. Для этого следует вместо набора имен файлов в скобках ввести строку вызова команды в апострофах (не в кавычках!). Строка передается для выполнения интерпретатору команд cmd.exe, а вывод этой команды записывается в память и обрабатывается так, как будто строка вывода взята из файла. Например, следующий командный файл:

      @ECHO OFF CLS ECHO Имена переменных среды: ECHO. FOR /F "DELIMS= texample">FOR допускается применение тех же синтаксических конструкций (операторов), что и для заменяемых параметров (табл. 3.4). 
      Таблица 3.4. Операторы для переменных команды FOR
      ОператорыОписание
      %~FiПеременная %i расширяется до полного имени файла
      %~DiИз переменной %i выделяется только имя диска
      %~PiИз переменной %i выделяется только путь к файлу
      %~NiИз переменной %i выделяется только имя файла
      %~XiИз переменной %i выделяется расширение имени файла
      %~SiЗначение операторов N и X для переменной %i изменяется так, что они работают с кратким именем файла

      Замечание

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

      Например, если мы находимся в каталоге C:\Program Files\Far и запустим командный файл следующего содержания:

      @ECHO OFF CLS FOR %%i IN (*.txt) DO ECHO %%~Fi то на экран выведутся полные имена всех файлов с расширением txt: C:\Program Files\Far\Contacts.txt C:\Program Files\Far\FarFAQ.txt C:\Program Files\Far\Far_Site.txt C:\Program Files\Far\License.txt C:\Program Files\Far\License.xUSSR.txt C:\Program Files\Far\ReadMe.txt C:\Program Files\Far\register.txt C:\Program Files\Far\WhatsNew.txt

      Циклы и связывание времени выполнения для переменных

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

      SET a= FOR %%i IN (Раз,Два,Три) DO SET a=%a%%%i ECHO a=%a%

      В результате его выполнения на экран будет выведена строка "a=Три" , то есть фактически команда

      FOR %%i IN (Раз,Два,Три) DO SET a=%a%%%i
      FOR %%i IN (Раз,Два,Три) DO SET a=%%i

      Для исправления ситуации нужно, как и в случае с составными выражениями, вместо знаков процента ( % ) использовать восклицательные знаки и предварительно включить режим связывания времени выполнения командой SETLOCAL ENABLEDELAYEDEXPANSION . Таким образом, наш пример следует переписать следующим образом:

      SETLOCAL ENABLEDELAYEDEXPANSION SET a= FOR %%i IN (Раз,Два,Три) DO SET a=!a!%%i ECHO a=%a%

      В этом случае на экран будет выведена строка "a=РазДваТри" .

      Добавить комментарий

      Ваш адрес email не будет опубликован. Обязательные поля помечены *