Как передать параметры в функцию?


11

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

function foo($arg1, $arg2)
{
  echo $arg1
  echo $arg2.FullName
}

echo "0: $($args[0])"
echo "1: $($args[1])"
$items = get-childitem $args[1] 
$items | foreach-object -process {foo $args[0] $_}

Я хочу передать , $arg[0]как $arg1к foo, и , $arg[1]как $arg2. Однако, это не работает, по какой-то причине $arg1всегда пусто:

PS C:\Users\sbi> .\test.ps1 blah .\Dropbox
0: blah
1: .\Dropbox
C:\Users\sbi\Dropbox\Photos
C:\Users\sbi\Dropbox\Public
C:\Users\sbi\Dropbox\sbi
PS C:\Users\sbi>

Примечание . "blah"Параметр не передается как $arg1.

Я абсолютно уверен, что это что-то смешно простое (я только начал заниматься PS и все еще чувствую себя очень неуклюже), но я уже час бьюсь об этом, и ничего не могу найти.

Ответы:


2

$arg[]Массив , как представляется , теряют объем внутри ForEach-Object .

function foo($arg1, $arg2)
{
  echo $arg1
  echo $arg2.FullName
}

echo "0: $($args[0])"
echo "1: $($args[1])"
$zero = $args[0]
$one = $args[1]
$items = get-childitem $args[1] 
$items | foreach-object {
    echo "inner 0: $($zero)"
    echo "inner 1: $($one)"
}

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

10

Причина, по которой $ args [0] ничего не возвращает в объекте foreach, заключается в том, что $ args - это автоматическая переменная, которая принимает в команду безымянные, несопоставимые параметры, а объект foreach - это новая команда. Для блока процесса нет никаких несопоставимых параметров, поэтому $ args [0] имеет значение null.

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

param ($SomeText, $SomePath)
function foo($arg1, $arg2)
{
  echo $arg1
  echo $arg2.FullName
}

echo "0: $SomeText"
echo "1: $SomePath"
$items = get-childitem $SomePath
$items | foreach-object -process {foo $SomeText $_}

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


Мля. Именно по этой причине я избегаю встроенных функций, таких как Foreach-Object, в пользу использования хорошей старой конструкции цикла foreach.
Тревор Салливан

Ах хорошо. Это я понимаю сейчас. Черт, это кажется довольно нелогичным!
2012 года

3

Попробуйте что-то вроде этого:

# Use an advanced function
function foo
{
  [CmdletBinding()]
  param (
      [string] $arg1
    , [string] $arg2
  )

  Write-Host -Object $arg1;
  Write-Host -Object $arg2;
}

# Create array of "args" to emulate passing them in from command line.
$args = @('blah', 'c:\test');

echo "0: $($args[0])"
echo "1: $($args[1])"

# Force items to be returned as an array, in case there's only 1 item returned
$items = @(Get-ChildItem -Path $args[1]);
Write-Host -Object "There are $($items.Count) in `$items";

# Iterate over items found in directory
foreach ($item in $items) {
    foo -Arg1 $args[0] -Arg2 $item.FullName
}

Это «принудительное возвращение элементов в виде массива» - это то, что я действительно должен добавить. Спасибо за подсказку!
СБи

Да, нужно быть осторожным, если вы получите только один элемент обратно - приведя его явно к массиву, вы получите согласованные результаты, так что вы можете перебрать его, используя foreach.
Тревор Салливан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.