Parametreler bir işleve nasıl aktarılır?


11

PS komut dosyasında bir SVN çalışma kopyasını işlemek gerekiyor, ancak işlevlere argümanlar geçirmede sorun yaşıyorum. İşte sahip olduğum şeyler:

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] $_}

Geçmek istiyorum $arg[0]olarak $arg1için foo, ve $arg[1]olarak $arg2. Ancak, işe yaramaz, bazı nedenlerden dolayı $arg1her zaman boştur:

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>

Not:"blah" parametresi olarak kabul edilmez $arg1.

Kesinlikle çok komik bir şey olduğundan eminim (sadece PS yapmaya başladım ve hala çok sakar hissediyorum), ama şimdi bir saatten fazla bir süredir başımı buna çarptım ve hiçbir şey bulamıyorum.

Yanıtlar:


2

$arg[]Dizi içindeki kaybetmek kapsamı görünen ForEach-Nesne .

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

Şimdiye kadar aldığım üç cevaptan herhangi birini kabul edebilirdim, ama bunu seçeceğim, çünkü bu ne yaptığımı gösteriyor.
sbi

10

$ Args [0] 'ın foreach nesnesinde herhangi bir şey döndürmemesinin nedeni, $ args komutunun adlandırılmamış, eşleşmeyen parametreleri bir komuta götüren ve foreach nesnesinin yeni bir komut olmasıdır. İşlem bloğu için eşleşmeyen parametre yok, bu yüzden $ args [0] null.

Yardımcı olabilecek bir şey, komut dosyalarınızın işlevler gibi parametrelere sahip olabilmesidir.

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 $_}

Parametrelerinizden daha fazla işlevsellik istemeye başladığınızda , $ args'den şu anda kullanabileceğimiz mevcut gelişmiş parametrelere parametrelerin ilerlemesi hakkında yazdığım bir blog yayınına göz atmak isteyebilirsiniz .


Falan. Bunun nedenleri, iyi ham ham foreach döngü yapısını kullanmak lehine Foreach-Object gibi yerleşiklerden kaçınmamın nedenleridir.
Trevor Sullivan

Ah tamam. Bunu şimdi anlıyorum. Kahretsin, bu oldukça mantıksız görünüyor!
sbi

3

Bunun gibi bir şey deneyin:

# 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
}

Bu "bir dizi olarak döndürülecek öğeleri zorla" gerçekten eklemem gereken bir şeydir. İpucu için teşekkürler!
sbi

Evet, sadece tek bir öğeyi geri alırsanız dikkatli olmalısınız - açıkça bir dizi olarak yayınlayarak, tutarlı sonuçlar elde edersiniz, böylece kullanarak tekrarlayabilirsiniz foreach.
Trevor Sullivan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.