จะส่งพารามิเตอร์ไปยังฟังก์ชันได้อย่างไร


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 วัตถุ

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-object นั่นคือ $ args เป็นตัวแปรอัตโนมัติที่รับพารามิเตอร์ที่ไม่มีชื่อและไม่ตรงกันกับคำสั่งและ foreach-object เป็นคำสั่งใหม่ ไม่มีพารามิเตอร์ที่ไม่ตรงกันสำหรับบล็อกกระบวนการดังนั้น $ 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 ถึงพารามิเตอร์ขั้นสูงในปัจจุบันที่เราสามารถใช้ได้ตอนนี้


blah เหตุผลเช่นนี้คือเหตุผลที่ฉันหลีกเลี่ยงบิวด์อินเช่น Foreach-Object เพื่อใช้การสร้างลูป foreach ลูป 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

ใช่ต้องเป็นระวังหากคุณจะได้รับกลับรายการเดียว - foreachโดยการหล่ออย่างชัดเจนเป็นอาร์เรย์คุณจะได้รับผลที่สอดคล้องกันเพื่อให้คุณสามารถย้ำกว่าโดยใช้
เทรเวอร์ซัลลิแวน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.