関数にパラメーターを渡す方法は?


11

PSスクリプトでSVN作業コピーを処理する必要がありますが、関数に引数を渡すことができません。ここに私が持っているものがあります:

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]$arg1foo、そして$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)"
}

これまでに得た3つの答えはどれでも受け入れることができますが、これは私がやったことを示しているので、これを選びます。
sbi

10

$ args [0]がforeach-objectに何も返さない理由は、$ argsがコマンドに無名の一致しないパラメーターを受け取る自動変数であり、foreach-objectが新しいコマンドであるためです。プロセスブロックには一致しないパラメーターがないため、$ args [0]はnullです。

役立つ1つのことは、スクリプトが関数のようにパラメーターを持つことができることです。

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ループ構造を使用することにしました。
Trevor Sullivan

ああ、わかりました。これは今私が理解しています。くそー、それはかなり直観に反するようですが!
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

ええ、アイテムを1つだけ取得する場合は注意が必要です。明示的に配列としてキャストすると、一貫した結果が得られるため、を使用して反復できますforeach
Trevor Sullivan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.