Feeds:
Записи
Комментарии

Archive for Июль 2011

При просмотре справки, можно увидеть, что – параметр -Process ,может принимать массив аргументов.

PS 1 >  get-help ForEach-Object -Parameter process

-Process <ScriptBlock[]>

Specifies the script block that is applied to each incoming object.

Required?                    true

Position?                    1

Но на деле не все так прозрачно, как кажется и не является ошибкой в документации. Параметр Process принимает все несвязанные аргументы, в чем легко можно убедиться.  Для этого воспользуемся cmdlet Trace-Command.

Trace-Command -Name ParameterBinding -PSHost -Expression {

dir | foreach {$sum=0} {$sum+=$_.length} {$sum}

}

DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [ForEach-Object]

DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [ForEach-Object]

DEBUG: ParameterBinding Information: 0 : BIND REMAININGARGUMENTS cmd line args to param: [Process]

Думаю более наглядно будет использовать cmdlet Set-PSDebug. В нашем примере параметр Process принимает 3 scriptblocks ({$sum=0} {$sum+=$_.length} {$sum}),параметр -Begin и –End ничего не принимают. Если параметру -Process два scriptblocks ,а параметр –Begin не указан, то первый scriptblock будет относиться к параметру –Begin, а второй к параметру -Process. Если параметр -Begin определен и принимает аргументы, -Process имеет два scriptblocks,то первый scriptblock относится к параметру –Process,второй к –End. Если оба параметра определенны -Begin и     -End,то все остальные scriptblocks будут привязаны к -Process.

Установим перед этим параметр –Trace 2 у cmdlet Set-PSDebug.

Set-PSDebug –Trace 2

1)       Один scriptblock  — используется только -Process.

PS  >  dir | foreach {$_.length}

DEBUG:    1+  <<<< dir | foreach {$_.length}

DEBUG:    1+ dir | foreach {$_. <<<< length}

DEBUG:    1+ dir | foreach {$_. <<<< length}

Здесь мы видим, что выполняется только блок  -Process(<<<< — указывает где происходит действие.)

2)       Два scriptblocks – первый относится к -Begin,второй к -Process.

PS >  dir | foreach {$sum=0}{$_.length}

DEBUG:    1+  <<<< dir | foreach {$sum=0}{$_.length}

DEBUG:    1+ dir | foreach {$sum= <<<< 0}{$_.length}

DEBUG:     ! SET $sum = ‘0’.

DEBUG:    1+ dir | foreach {$sum=0}{$_. <<<< length}

DEBUG:    1+ dir | foreach {$sum=0}{$_. <<<< length}

Здесь мы видим, что блок  -Begin выполняется только один раз ({$sum= <<<< 0}),дальше выполняется только блок -Process.

3)       Три scriptblocks – первый относится к -Begin,второй к -Process,третий к -End.

PS >  dir | foreach {$sum=0}{$sum+=$_.length}{$sum}

DEBUG:    1+  <<<< dir | foreach {$sum=0}{$sum+=$_.length}{$sum}

DEBUG:    1+ dir | foreach {$sum= <<<< 0}{$sum+=$_.length}{$sum}

DEBUG:     ! SET $sum = ‘0’.

DEBUG:    1+ dir | foreach {$sum=0}{$sum+= <<<< $_.length}{$sum}

DEBUG:     ! SET $sum = ‘0’.

Вывод обрезан.

DEBUG:    1+ dir | foreach {$sum=0}{$sum+=$_.length}{$sum <<<< }

Здесь мы видим, что блок -Begin выполняется только один раз ({$sum= <<<< 0}),дальше выполняется только блок -Process, в конце происходит вывод суммы при выполнении блока –End({$sum <<<< }).

4)       Три и более scriptblocks — первый относится к  -Begin,последний к  -End,остальные к  -Process.

PS  >  dir | foreach {$sum=0}{$sum+=$_.length}{$_.Name}{$sum}

DEBUG:    1+  <<<< dir | foreach {$sum=0}{$sum+=$_.length}{$_.Name}{$sum}

DEBUG:    1+ dir | foreach {$sum= <<<< 0}{$sum+=$_.length}{$_.Name}{$sum}

DEBUG:     ! SET $sum = ‘0’.

DEBUG:    1+ dir | foreach {$sum=0}{$sum+= <<<< $_.length}{$_.Name}{$sum}

DEBUG:     ! SET $sum = ‘0’.

DEBUG:    1+ dir | foreach {$sum=0}{$sum+=$_.length}{$_. <<<< Name}{$sum}

Вывод обрезан.

DEBUG:    1+ dir | foreach {$sum=0}{$sum+=$_.length}{$_.Name}{$sum <<<< }

Здесь мы видим, что блок  -Begin выполняется только один раз ({$sum= <<<< 0}),дальше выполняется блок  -Process,который принимает уже массив из двух элементов (сначала выполняется {$sum+= <<<< $_.length} ,следующий за ним {$_. <<<< Name} ), в конце происходит вывод суммы при выполнении блока  -End({$sum <<<< }).

Как передать массив объектов параметру –Process:

1)      Явно указать параметры и аргументы для -Begin и -End.

PS >  1..2 | foreach -begin {‘Я блок Begin’} -end {‘Я блок End’} -Process {‘-‘*20},{ ‘x’*$_},{$_},{‘-‘*20}

Я блок Begin

———————

x

1

———————

———————

xx

2

———————

Я блок End

2)      Вместо -Begin и –End использовать {}

PS >  1..2 | foreach {}{‘-‘*20}{ ‘x’*$_}{$_}{‘-‘*20}{}

———————

x

1

———————

———————

xx

2

———————

Реклама

Read Full Post »