Перейти к содержимому

Непонятные штуки — $_ и % в Power Shell

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

# Получаем объекты представляющие файлы в переменную $files
$Files = dir C:roottest
# С помощью for: 
#    1) объявляем переменную $i, и присваиваем ей значение 0
#    2) указываем условие повторения цикла($i меньше количества файлов)
#    3) указываем что после каждого выполнения цикла надо увеличить $i на единицу
for ($i=0; $i -lt $files.Count; $i++)
{
    # Пока условие удовлетворяется, вызываем утилиту md5.exe, передавая ей в
    # качестве аргумента элемент массива файлов под номером $i (отсчет идет с 0)
    md5.exe $files[$i]
}

И вот результат:

For очень популярен, присутствует во множестве языков, но тем не менее обладает некоторыми недостатками. Во первых это необходимость использования временной переменной для перебора, во вторых — излишняя сложность конструкции. Гораздо проще для перебора группы объектов использовать ForEach:

# Получаем объекты представляющие файлы в переменную $files
$Files = dir C:roottest
# Каждый объект из $Files по очереди помещается в переменную $File
ForEach ($File in $Files)
{
    # ... и выполняется блок кода...
    md5.exe $File
}

Или еще короче:

Способ отличный, но тоже не лишен недостатков. Обычно работая в консоли я сначала выполняю команду dir или get-*, для того чтобы посмотреть на список объектов, а затем уже хочу обработать их. Для использования ForEach мне пришлось бы возвращаться в начало строки, дописывать там Foreach ($obj in ( затем идет код получения объектов, затем закрывающие скобки и затем уже код для выполнения. Не слишком удобно для быстрой работы. Но к счастью есть командлет Foreach-Object. В него можно просто перенаправить полученные объекты, и указать блок кода для выполнения. При этом даже не нужно указывать имя для временного объекта — он всегда будет представлен под именем $_ 

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

Удобнее может быть только использование PowerShell’овских командлетов или скриптов умеющих обрабатывать объекты получаемые по конвейеру. Тут уже не надо никаких For и Foreach 

На самом деле я изложил тут лишь одно применение переменной $_ (кстати она называется «Default variable»), хоть и наиболее популярное. $_ используется еще во многих местах, обычно представляя «текущий объект». Но думаю теперь вам будет проще понять и эти случаи. Например в командлете Where-Object $_ исполняет ту же роль что и в ForeEach-Object — содержит текущий объект конвейера. А в блоке обработки ошибок (trap), за $_ будет скрываться объект текущей ошибки.

Опубликовано вPowershell

Ваш комментарий будет первым

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

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