Як передати параметри функції?


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.

Я абсолютно впевнений, що це щось надзвичайно просто (я тільки почав займатися ПС і все ще відчуваю себе дуже незграбно), але я вже більше години бовтаюсь головою, і нічого не можу знайти.

Відповіді:


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)"
}

Я міг би прийняти будь-який з трьох відповідей, які я отримав поки що, але я виберу цей, бо це показує, що я в кінцевому підсумку робив.
sbi

10

Причина того, що $ args [0] нічого не повертає в об'єкті foreach, полягає в тому, що $ args - це автоматична змінна, яка приймає в команду неназвані, незрівняні параметри, а об'єкт foreach - нова команда. Немає ніяких невідповідних параметрів для блоку процесу, тому $ args [0] є нульовим.

Одне, що може допомогти, це те, що у ваших сценаріїв можуть бути параметри, як і функції.

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, на користь використання хорошої конструкції циклічного циклу передбачення.
Тревор Салліван

А, добре. Це я зараз розумію. Чорт, це здається цілком контрсуєтивним, хоча!
sbi

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
}

Те, що я мушу додати, що "примусові елементи, які потрібно повернути як масив". Дякую за підказку!
sbi

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