В одной из своих статей я уже рекомендовал отказаться от пакетных файлов (сценарии оболочки Cmd.exe) и сосредоточиться на изучении PowerShell. Конечно, освоение новых технологий невозможно без усилий, и Windows PowerShell — не исключение.

Если вы согласны со мной, то придется отказаться от некоторых навыков в подготовке пакетных файлов и освоить новые, чтобы перейти к PowerShell. В Cmd.exe используются специальные символы, у многих из которых нет эквивалентов в PowerShell (или они означают что-то иное). В данной статье описаны специальные символы, используемые в Cmd.exe, и их отличия в применении по сравнению с PowerShell.

Символ @

По умолчанию Cmd.exe отображает каждую выполняемую команду пакетного файла на экране. Отображение отдельных команд можно отменить, поставив символ @ перед командой, а чтобы запретить вывод на экран всех последующих команд в пакетном файле, следует применить команду Echo Off.

Отображение команд полезно при отладке пакетного файла, но большинство авторов пакетных файлов вставляют команду @Echo Off в начале каждого пакетного файла, чтобы не выводить команды на экран (символ @ в начале команды предотвращает отображение самой команды, отключающей вывод на экран). В отличие от Cmd.exe, в PowerShell нет отображения команд, поэтому команда @Echo Off не нужна.

В PowerShell символ @ используется для создания массивов или хэш-таблиц. Cmd.exe не поддерживает массивы и хэш-таблицы, но вы можете прочитать об этих структурах в разделах справки about_Arrays и about_Hash_Tables для PowerShell.

Символ %

У символа % есть несколько особых значений в оболочке Cmd.exe: он задает переменные среды и два вида замены параметров. Рассмотрим их.

Переменные среды. В Cmd.exe символы % окружают имя переменной среды, и интерпретатор развертывает переменную до ее значения. Например, %SystemRoot% расширяется до C:\Windows. В PowerShell такой синтаксис не используется; нужно ввести $Env:SystemRoot (то есть $Env: с последующим именем переменной среды).

Замена параметра команды For. Синтаксис команды For довольно сложен; он обеспечивает последовательную обработку набора элементов (например, строк, файлов, каталогов и т.д.) и выполнение команды для каждого результирующего элемента. Символ %, за которым следует единственная буква от a до z, представляет собой параметр, который Cmd.exe заменяет текущим элементом. Например, в Cmd.exe команда

for %p in (A B) do echo %p

выполняет команду Echo дважды: один раз для буквы A и второй раз для буквы B. Обратите внимание, что необходимо удвоить символ B %, если вы используете команду For в пакетном файле, а не вводите ее в ответ на приглашение Cmd.exe.

Однако в PowerShell предусмотрено несколько способов последовательной обработки наборов элементов. Команда ForEach-Object — ближайший аналог команды For из Cmd.exe. Показанная выше строка в PowerShell примет следующий вид:

«A",»B«| foreach-object { $_ }

$_ — эквивалент %p в команде For из Cmd.exe приведенного выше примера. Это специальная переменная, означающая»текущий объект из конвейера«, который в данном примере заменяется каждым строковым объектом (»A«, затем»B«). Кавычки необходимы на левой стороне вертикальной черты (|), потому что иначе PowerShell не распознает, что имеет дело со строковыми объектами.

В PowerShell символ % используется как псевдоним (подставное имя команды) для команды ForEach-Object, поэтому указанную выше команду PowerShell можно записать следующим образом:

»A«,"B» | % { $_ }

Псевдоним % понятен программистам Perl, но сбивает с толку тех, что привык к другому использованию % в пакетных файлах. Во избежание путаницы рекомендуется вводить имя команды (ForEach-Object).

Подставляемые параметры. В пакетном файле символ %, за которым следует одна цифра от 0 до 9, заменяется на соответствующий параметр командной строки: %0 — имя пакетного файла, %1 — первый параметр в командной строке пакетного файла, %2 — второй параметр и т.д. На экране 1 показан пример пакетного файла, в котором используется подставляемый параметр.

 

Пример использования параметра подстановки
Экран 1. Пример использования параметра подстановки

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

Символ!

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

Эту особенность иллюстрирует экран 2. Можно было бы ожидать, что в выводе будут присутствовать символы A и B, но их нет. Это объясняется тем, что Cmd.exe развертывает ссылку на переменную среды TEST в пустую строку перед выполнением команды For.

 

Развертывание переменных среды
Экран 2. Развертывание переменных среды

Чтобы обойти эту особенность, необходимо включить задержку развертывания переменных среды окружения во время исполнения команды. Для этого добавьте ключевое слово Enabledelayedexpansion к команде Setlocal и замените символы %, окружающие имя переменной среды, символами! . На экране 3 показан обновленный пакетный файл и результаты.

 

Задержка развертывания переменных среды окружения во время исполнения
Экран 3. Задержка развертывания переменных среды окружения во время исполнения

В PowerShell таких странностей нет, поэтому связывание времени выполнения для переменных среды окружения не требуется. Вместо этого символ! в PowerShell используется как оператор «not» (идентично -not). Дополнительные сведения можно найти в разделе справки about_Logical_Operators для PowerShell.

Символы ( и )

В Cmd.exe используются скобки, ( и ), для вложенных последовательностей из многих команд и инструкции Else для команды If. Аналог в PowerShell — фигурные скобки, { и }. Фигурные скобки в PowerShell представляют фрагмент программного кода, именуемый блоком сценария Scriptblock.

Символ |

Вертикальная черта (|) указывает команде с правой стороны на необходимость принять вывод из команды слева от черты. Например, команда

type file.txt | sort

указывает команде Sort на необходимость принять в качестве входных данных вывод команды Type. Этот процесс называется конвейерной обработкой. Выводимые данные в Cmd.exe всегда представляют собой текст.

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

Символы < и >

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

sort < file.txt

можно заменить на

type file.txt | sort

Символ ^

Символ ^ (каре) в Cmd.exe служит одновременно символом экранирования специальных символов (escape-символ) и символом продолжения строки. На экране 4 показан пример его применения. Первый символ ^ в пакетном файле не позволяет Cmd.exe интерпретировать > как перенаправление вывода, а второй символ ^ указывает Cmd.exe, что четвертую строку пакетного файла следует интерпретировать как окончание третьей строки.

 

Два варианта использования символа ^
Экран 4. Два варианта использования символа ^

В PowerShell обратный апостроф (`) используется для избавления от специальных символов и продолжения строки вместо символа ^. Символ ^ не имеет специального значения в PowerShell.

Символ &

Символ & (амперсанд) используется в Cmd.exe в качестве разделителя команд, чтобы разместить несколько команд на одной строке. В PowerShell для этого используется символ; (точка с запятой).

Символ («)

Кавычки (») инкапсулируют параметры в Cmd.exe, то есть синтаксический анализатор командной строки извещается о том, что текст между кавычками является одним параметром, а не несколькими. Например, команда

dir C:\Program Files

Выполняет команду Dir с двумя параметрами: C:\Program и Files. Чтобы явно указать Cmd.exe, что мы намерены использовать один параметр, необходимо поместить путь в кавычки, то есть:

dir «C:\Program Files»

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

Кавычки действуют таким же образом для параметров PowerShell, хотя в PowerShell имеются свои правила для кавычек. Например, в PowerShell предусмотрены кавычки двух типов: двойные (") и одиночные ('). Одно из различий между двумя типами кавычек заключается в том, что PowerShell развертывает ссылки на переменные в строках с двойными, а не с одиночными кавычками. Подробную информацию об использовании кавычек в PowerShell можно найти в разделе справки about_Quoting_Rules.

Вносим ясность в применение символов

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

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