PowerShell 函數


PowerShell 中函數是一系列 PowerShell 語句的組合。當你通過函數的名稱調用函數時,函數中的語句會被順序的執行,就像在命令行中執行它們一樣。

從 hello world 開始

function Say-HelloWorld 
{ Write
-Host "hello world!" }

定義函數必須使用 function 關鍵字,並且為函數提供一個名稱。然后用花括號把 PowerShell 語句括起來。
調用函數的方式也很簡單,比如上面的函數連參數都沒有定義,直接寫函數名稱就可以了:

> Say-HelloWorld

函數的命名規則

PowerShell 中命令的命名是非常有特色的,都是 "動詞 - 名詞" 的模式。MS 也建議我們以同樣的模式來命名自定義的函數,以保證代碼的可讀性。
比如我們定義的函數 Say-HelloWorld 就遵循這樣的規則。再舉個例子,比如你要定義一個把日志信息寫到文件中的函數,那可能就要命名為 Write-Log 之類的名稱了。

MS 甚至對常用的名稱給出了具體的規范,有興趣的同學可以去讀讀:Approved Verbs for Windows PowerShell Commands

位置參數 $args

在 shell 世界中位置參數(Position Patameters)是普遍存在的。其實就是在函數或腳本中我們可以通過默認存在的變量 $args 來引用傳遞給函數或腳本的參數。$args 變量是一個數組,所以我們需要通過索引語法來引用具體的參數,如 $args[0],$args[1] …

我們在下面的函數中引用位置參數:

function Say-Hello
{
    Write-Host("Hello {0} {1}!" -f $args[0], $args[1])
}
> Say-Hello "Nick" "Li"

命名參數

除了使用位置參數,我們還可以在聲明函數時指定命名參數。使用命名的參數還可以為參數指定默認值。

function Say-Hello($name, $count=3)
{
    for(;$count -gt 0;$count--)
    {
        Write-Host("Hello {0}!" -f $name)
    }   
}
> Say-Hello "Nick" 2

作為 C# 程序員筆者比較喜歡把參數寫在小括號里面,但是在 PowerShell 中更常見的參數聲明方式為使用 Param 關鍵字:

function Say-Hello
{
    Param
    (
        $name,
        $count=3
    )

    for(;$count -gt 0;$count--)
    {
        Write-Host("Hello {0}!" -f $name)
    }   
}

這兩種聲明函數參數的方式是完全等價的,所以你可以選擇自己喜歡的方式。

在調用函數時,我們還可以通過指定參數名稱的方式為函數傳參:

> Say-Hello -name "Jack" -count 5

從 Pipeline 輸入函數參數

PowerShell 中的函數可以很輕松的支持從 Pipeline 輸入參數,下面是一個簡單的 demo:

function Say-Hello
{
    Param
    (
        [parameter(Mandatory=$true, ValueFromPipeline=$true)]
        $name
    )
    process
    {
        Write-Host("Hello {0}!" -f $name)
    }
}

在上面的函數聲明中我們把函數的主體放入了 process 程序塊。在 process 塊中的語句會根據 Pipeline 中對象的個數執行多次。也就是說,如果我們通過 Pipeline 為函數傳遞 3 個參數,那么 process 塊中的代碼就會執行 3 次。
[parameter(Mandatory=$true, ValueFromPipeline=$true)] 說明可以通過 Pipeline 傳遞參數 name。試一下通過 Pipeline 傳參:

> "Jack","Nick","Alice" | Say-Hello

注意,此時還可以通過 Say-Hello "Nick" 的方式調用函數,我們只是在基本功能的基礎上添加了對 Pipeline 的支持。

作用域

函數只存在於創建它的上下文中(scope),比如定義函數的腳本。如果想要在一個腳本中引用在另外一個腳本中定義的函數,需要使用 source(.) 命令。在當前的腳本 A 中使用 source 命令並指定另外一個腳本 B 作為參數,會把 B 中定義的函數、別名和變量引入到腳本 A 的上下文中(scope)。
比如筆者在 Write-Log.ps1 文件中定義了函數 Write-Log,在另外一個腳本中使用 Write-Log 的方法為:
# 此處可以寫絕對路徑也可以寫相對路徑

. "./Write-Log.ps1"
Write-Log -Message 'It's a test message'

函數自身會創建一個上下文(scope),在函數中定義的變量在函數外部是不可見的。
但是在函數內部卻可以訪問在函數外部定義的變量,比如下面的 demo:

$world = "Hello world!"
function Say-Hello 
{ Write
-Host($world) }
> Say-Hello


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM