powershell - मैं PowerShell में किसी फ़ंक्शन में एकाधिक पैरामीटर कैसे पास करूं?




7 Answers

PowerShell (सभी संस्करणों) में फ़ंक्शंस में कॉल करने वाले पैरामीटर स्पेस से अलग होते हैं, अल्पविराम से अलग नहीं होते हैं। साथ ही, कोष्ठक पूरी तरह Set-StrictMode यदि Set-StrictMode सक्रिय है तो Set-StrictMode 2.0 (या बाद में) में एक पार्स त्रुटि उत्पन्न होगी। अभिभावक तर्क केवल .NET विधियों में उपयोग किए जाते हैं।

function foo($a, $b, $c) {
   "a: $a; b: $b; c: $c"
}

ps> foo 1 2 3
a: 1; b: 2; c: 3

यदि मेरे पास एक ऐसा फ़ंक्शन है जो एक से अधिक स्ट्रिंग पैरामीटर स्वीकार करता है, तो पहला पैरामीटर इसे आवंटित सभी डेटा प्राप्त करता है, और शेष पैरामीटर खाली के रूप में पास किए जाते हैं।

एक त्वरित परीक्षण स्क्रिप्ट:

Function Test([string]$arg1, [string]$arg2)
{
    Write-Host "`$arg1 value: $arg1"
    Write-Host "`$arg2 value: $arg2"
}

Test("ABC", "DEF")

उत्पन्न उत्पादन है

$arg1 value: ABC DEF
$arg2 value: 

सही आउटपुट होना चाहिए:

$arg1 value: ABC
$arg2 value: DEF

यह कई मशीनों पर v1 और v2 के बीच संगत लगता है, इसलिए जाहिर है, मैं कुछ गलत कर रहा हूं। क्या कोई वास्तव में क्या बता सकता है?




आप कोष्ठक के बिना PowerShell फ़ंक्शंस को कॉल करते हैं और अल्पविराम के रूप में अल्पविराम का उपयोग किए बिना। उपयोग करने का प्रयास करें:

   test "ABC" "DEF"

PowerShell में अल्पविराम (,) एक सरणी ऑपरेटर है, उदाहरण के लिए

   $a = "one", "two", "three"

यह तीन मानों के साथ एक सरणी में $ एक सेट करता है।




यहां कुछ अच्छे जवाब हैं, लेकिन मैं कुछ अन्य चीजों को इंगित करना चाहता था। फ़ंक्शन पैरामीटर वास्तव में एक ऐसा स्थान है जहां PowerShell चमकता है। उदाहरण के लिए, आप या तो उन्नत कार्यों में नाम या स्थितित्मक पैरामीटर हो सकते हैं जैसे:

function Get-Something
{
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [string] $Name,
         [Parameter(Mandatory=$true, Position=1)]
         [int] $Id
    )
}

फिर आप इसे पैरामीटर नाम निर्दिष्ट करके कॉल कर सकते हैं, या आप केवल स्थितित्मक पैरामीटर का उपयोग कर सकते हैं, क्योंकि आपने उन्हें स्पष्ट रूप से परिभाषित किया है। तो इनमें से कोई भी काम करेगा:

Get-Something -Id 34 -Name "Blah" 
Get-Something "Blah" 34

पहला उदाहरण काम करता है भले ही नाम दूसरा प्रदान किया गया हो, क्योंकि हमने स्पष्ट रूप से पैरामीटर नाम का उपयोग किया था। दूसरा उदाहरण स्थिति के आधार पर काम करता है, इसलिए नाम पहले होना चाहिए। जब संभव हो, मैं हमेशा पदों को परिभाषित करने की कोशिश करता हूं ताकि दोनों विकल्प उपलब्ध हों।

पावरशेल में पैरामीटर सेट को परिभाषित करने की क्षमता भी है। यह विधि ओवरलोडिंग के स्थान पर इसका उपयोग करता है, और फिर काफी उपयोगी है:

function Get-Something
{
    [CmdletBinding(DefaultParameterSetName='Name')]
    Param
    (
         [Parameter(Mandatory=$true, Position=0, ParameterSetName='Name')]
         [string] $Name,
         [Parameter(Mandatory=$true, Position=0, ParameterSetName='Id')]
         [int] $Id
    )
}

अब समारोह या तो एक नाम, या एक आईडी ले जाएगा, लेकिन दोनों नहीं। आप उन्हें स्थितित्मक रूप से, या नाम से उपयोग कर सकते हैं। चूंकि वे एक अलग प्रकार हैं, इसलिए PowerShell इसे समझ जाएगा। तो ये सब काम करेंगे

Get-Something "some name"
Get-Something 23
Get-Something -Name "some name"
Get-Something -Id 23

आप विभिन्न पैरामीटर सेट में अतिरिक्त पैरामीटर भी निर्दिष्ट कर सकते हैं। (यह स्पष्ट रूप से एक सुंदर मूल उदाहरण था) फ़ंक्शन के अंदर, आप यह निर्धारित कर सकते हैं कि $ PsCmdlet.ParameterSetName प्रॉपर्टी के साथ कौन सा पैरामीटर सेट उपयोग किया गया था। उदाहरण के लिए:

if($PsCmdlet.ParameterSetName -eq "Name")
{
    Write-Host "Doing something with name here"
}

फिर, संबंधित पक्ष नोट पर, PowerShell में पैरामीटर सत्यापन भी है। यह मेरी पसंदीदा पावरशेल सुविधाओं में से एक है, और यह आपके कार्यों के अंदर कोड को बहुत साफ बनाता है। कई सत्यापन हैं जिनका आप उपयोग कर सकते हैं। कुछ उदाहरण हैं

function Get-Something
{
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [ValidatePattern('^Some.*')]
         [string] $Name,
         [Parameter(Mandatory=$true, Position=1)]
         [ValidateRange(10,100)]
         [int] $Id
    )
}

पहले उदाहरण में, ValidatePattern एक नियमित अभिव्यक्ति स्वीकार करता है जो आपूर्ति किए गए पैरामीटर को आश्वस्त करता है कि आप क्या उम्मीद कर रहे हैं। यदि ऐसा नहीं होता है, तो एक अंतर्ज्ञानी अपवाद फेंक दिया जाता है, जो आपको बताता है कि क्या गलत है। तो उस उदाहरण में, 'कुछ' ठीक काम करेगा, लेकिन 'ग्रीष्मकालीन' सत्यापन पास नहीं करेगा।

ValidateRange यह सुनिश्चित करता है कि पैरामीटर मान उस सीमा के बीच है जो आप पूर्णांक के लिए अपेक्षा करते हैं। तो 10 या 99 काम करेंगे, लेकिन 101 अपवाद फेंक देगा।

एक और उपयोगी एक ValidateSet है, जो आपको स्पष्ट रूप से स्वीकार्य मानों की एक सरणी को परिभाषित करने की अनुमति देता है। अगर कुछ और दर्ज किया गया है, तो एक अपवाद फेंक दिया जाएगा। अन्य भी हैं, लेकिन शायद सबसे उपयोगी एक मान्य है। यह एक स्क्रिप्ट ब्लॉक लेता है जिसे $ true का मूल्यांकन करना चाहिए, इसलिए आकाश सीमा है। उदाहरण के लिए:

function Get-Something
{
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [ValidateScript({ Test-Path $_ -PathType 'Leaf' })]
         [ValidateScript({ (Get-Item $_ | select -Expand Extension) -eq ".csv" })]
         [string] $Path
    )
}

इस उदाहरण में, हमें न केवल आश्वासन दिया जाता है कि $ पथ मौजूद है, लेकिन यह एक फ़ाइल है, (एक निर्देशिका के विपरीत) और इसमें एक .csv एक्सटेंशन है। ($ _ आपके स्क्रिप्टब्लॉक के अंदर पैरामीटर को संदर्भित करता है।) यदि आप उस स्तर की आवश्यकता है, तो आप बहुत बड़े, बहु-रेखा स्क्रिप्ट ब्लॉक भी पास कर सकते हैं, या मैंने यहां कई स्क्रिप्टब्लॉक का उपयोग किया है। यह बेहद उपयोगी है, और अच्छे साफ कार्यों और सहज अपवादों के लिए बनाता है।




अगर तुम कोशिश करो:

PS > Test("ABC", "GHI") ("DEF")

आपको मिला:

$arg1 value: ABC GHI
$arg2 value: DEF

तो आप देखते हैं कि कोष्ठक पैरामीटर को अलग करता है

अगर तुम कोशिश करो:

PS > $var = "C"
PS > Test ("AB" + $var) "DEF"

आपको मिला:

$arg1 value: ABC
$arg2 value: DEF

अब आप कोष्ठक की कुछ तत्काल उपयोगिता मिल सकती है - एक स्पेस अगले पैरामीटर के लिए विभाजक नहीं बन जाएगा - इसके बजाय आपके पास एक eval function है।




Function Test([string]$arg1, [string]$arg2)
{
    Write-Host "`$arg1 value: $arg1"
    Write-Host "`$arg2 value: $arg2"
}

Test("ABC") ("DEF")



मैं निम्नलिखित पहले बताता हूं:

आम समस्या एकवचन रूप $arg का उपयोग कर रही है, जो गलत है।
यह हमेशा $args रूप में बहुवचन होना चाहिए।

समस्या यह नहीं है।
वास्तव में, $arg कुछ और हो सकता है। समस्या अल्पविराम और parantheses का उपयोग था।
मैं निम्नलिखित कोड चलाता हूं जो काम करता है और आउटपुट निम्नानुसार है:

कोड:

Function Test([string]$var1, [string]$var2)
{
    Write-Host "`$var1 value: $var1"
    Write-Host "`$var2 value: $var2"
}

टेस्ट "एबीसी" "डीईएफ"

आउटपुट:

$ var1 मान: एबीसी $ var2 मान: डीईएफ




चूंकि यह अक्सर एक बार देखा गया प्रश्न है, मैं यह उल्लेख करना चाहता हूं कि PowerShell फ़ंक्शन को अनुमोदित क्रियाओं का उपयोग करना चाहिए (कार्य नाम के रूप में Verb-Noun )। इसके अलावा आप पैरामीटर अनिवार्य है और पैरामीटर की स्थिति जैसे चीजों को निर्दिष्ट कर सकते हैं:

function Test-Script
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true, Position=0)]
        [string]$arg1,

        [Parameter(Mandatory=$true, Position=1)]
        [string]$arg2
    )

    Write-Host "`$arg1 value: $arg1"
    Write-Host "`$arg2 value: $arg2"
}

फ़ंक्शन पर पैरामीटर पास करने के लिए आप या तो स्थिति का उपयोग कर सकते हैं:

Test-Script "Hello" "World"

या आप पैरामीटर नाम निर्दिष्ट करते हैं:

Test-Script -arg1 "Hello" -arg2 "World"

जब आप सी # के भीतर कोई फ़ंक्शन कॉल करते हैं तो आप ब्रांड्स का उपयोग नहीं करते हैं

मैं एक पैरामीटर का उपयोग करते समय हमेशा पैरामीटर नामों को पारित करने की अनुशंसा करता हूं, क्योंकि यह अधिक पठनीय है




Related


Tags

powershell