Powershell指定函数的返回值 3


一个或多个返回值

Powershell不像它编程语言,它的函数可以有多个返回值。如果你直接调用函数,返回值会在控制台输出。当然你也可以将结果存储在一个变量中进一步处理。
下面的例子演示返回一个值:

function Square([double]$num)
{
    return $num*$num
}
#在控制台输出结果
Square 9.87
#97.4169

#将结果赋值给变量
$value=Square 9.87
$value
#97.4169

#返回值为Double类型
$value.GetType().FullName
#System.Double

下面的例子演示返回多个值

function gbMeasure($amount)
{
    "$amount GB=$($amount) GB"
    "$amount GB=$($amount*1gb/1mb) MB"
    "$amount GB=$($amount*1gb/1kb) KB"
    "$amount GB=$($amount*1gb) B"
}

#函数返回4个值
gbMeasure 1
# 1 GB=1 GB
# 1 GB=1024 MB
# 1 GB=1048576 KB
# 1 GB=1073741824 B

#将所有的返回值存储在一个变量中
$result=gbMeasure 1
$result

# 1 GB=1 GB
# 1 GB=1024 MB
# 1 GB=1048576 KB
# 1 GB=1073741824 B

#所有的返回值会自动存储在一个数组中
$result=gbMeasure 1
$result.GetType().Name

# Object[]

#通过索引访问每个返回值
$result=gbMeasure 1
$result[3]
# 1 GB=1073741824 B

总结一下,如果一个函数返回一个值,像其它编程语言一样,这个值包括她的类型信息会直接返回。但是如果遇到多个返回值,Powershell会将所有的返回值自动构造成一个Object数组。可以通过索引访问数组。

Return语句

Powershell会将函数中所有的输出作为返回值,但是也可以通过return语句指定具体的我返回值。
Return 语句会将指定的值返回,同时也会中断函数的执行,return后面的语句会被忽略。

function test($num)
{
    1
    9
    return 10
    4
    6
}
test
# 1 和 9 作为输出会返回
# return语句中的10 也会返回
# return 语句后的4和6会被忽略

#1
#9
#10

访问返回值

一个函数返回了一个值还是多个值,是可以验证的。下面的例子会产生随机数,如果没有指定个数,默认会返回一个随机数,否则会返回指定个数的随机数。

Function lottery([int]$number=1)
{
$rand = New-Object system.random
For ($i=1; $i -le $number; $i++) {
$rand.next(1,50)
}
}
# 参数为空时,返回值不是数组:
$result = lottery
$result -is [array]
# False
# 如果指定多个随机数是,返回值是数组类型:
$result = lottery 10
$result -is [array]
# True

从函数的返回值中消除输出

函数默认会将函数中的所有输出作为函数的返回值返回,这样很方便。但有时可能会将不必要的输出误以为返回值。写脚本程序时,可能需要自定义一些函数,这个函数可能只需要一个返回值,但是为了提高函数的可读性,可能会在函数增加一些注释输出行。

Function Test()
{
    "Try to calculate."
    "3.1415926"
    "Done."
}

#保存在变量中输出,
$value=Test
$value
# Try to calculate.
# 3.1415926
# Done.

#如果要过滤注释,只输出,不作为返回值,
#可以使用Write-Host命令
Function Test()
{
    Write-Host "Try to calculate."
    "3.1415926"
    Write-Host "Done."
}
# 在变量值中保存返回值,在控制台输出注释行
$value=Test
# Try to calculate.
# Done.

# 测试返回值
$value
# 3.1415926

使用调试信息报告

可能输出这些函数中临时提示信息,给函数的返回值造成干扰。要解决这个问题,除了上述的Write-Host,也可以使用Write-Debug命令。

Function Test()
{
    Write-Debug "Try to calculate."
    "3.1415926"
    Write-Debug "Done."
}
# Debug调试信息只会在调试模式下被输出
$value=Test
# 3.1415926

#如果你想通过显示调试信息调试函数,可以开启调试模式
$DebugPreference="Continue"
$value=Test
# 调试: Try to calculate.
# 调试: Done.

# 测试返回值
$value
# 3.1415926

#如果关闭调试模式,这些调试信息自然不会输出
$DebugPreference="SilentlyContinue"
$value=Test

使用Write-Debug有两个优势,首先调试信息会自动高亮显示,便于分析。其次,这些调试信息只会在调试模式开启时输出,控制起来更加方便。当然最重要的是这些临时信息无论什么时候也不会混淆在返回值。

抑制错误信息

函数中的错误信息,也有可能作为返回值的一部分,因为默认这些错误信息会直接输出。

Function ErrorTest()
{
    #该进程不存在
    Stop-Process -Name "www.mossfly.com"
}
ErrorTest

Stop-Process : 找不到名为“www.mossfly.com”的进程。请验证该进程名称,然后再次调用 cmdlet。
所在位置 C:UsersbaozhenDesktoptest.ps1:6 字符: 17
+     Stop-Process <<<<  -Name "www.mossfly.com"
    + CategoryInfo          : ObjectNotFound: (www.mossfly.com:String) [Stop-P
   rocess], ProcessCommandException
    + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.
   Commands.StopProcessCommand

 很明显,类似这样的错误提示信息,对调试程序很重要,但如果你觉得它不重要,特意要隐藏,可以使用$ErrorActionPreference进行设置。

 Function ErrorTest()
{
    #从这里开始隐藏所有的错误信息
    $ErrorActionPreference="SilentlyContinue"
    Stop-Process -Name "www.mossfly.com"
    #该进程不存在
}

#错误信息不会输出
ErrorTest

但是上面的做法并不明智,因为这样可能错过其它错误提示。所以最好的方式是处理完后,对$ErrorActionPreference进行复位。

Function ErrorTest()
{
    #从这里开始隐藏所有的错误信息
    $ErrorActionPreference="SilentlyContinue"
    Stop-Process -Name "www.mossfly.com"
    #该进程不存在

    #恢复$ErrorActionPreference,错误开始输出
    $ErrorActionPreference="Continue"

    2/0
}
ErrorTest
试图除以零。

所在位置 行:9 字符: 7
+ 2/ <<<< 0
+ CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : RuntimeException
本文链接: https://www.pstips.net/powershell-specify-return-value-from-function.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

回复 elale 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

3 条评论 “Powershell指定函数的返回值

  • elale

    Function lottery([int]$number=1)
    {
    $rand = New-Object system.random
    For ($i=1; $i -le $number; $i++) {
    $rand.next(1,50)
    }
    }
    # 参数为空时,返回值不是数组:
    $result = lottery
    $result -is [array]
    False

    刚才验证了一下,区分返回值是否数组似乎意义不大。因为即便不是数组,像上面这个,还是可以用$result.Count 计数(返回值是1),依然可以用$result[0]来访问第一个元素。

    这个不限于返回值。

    • Mooser Lee 文章作者

      $result.Count 在PowerShell 2.0时候是不行的。直到PowerShell 3.0才开始即使返回元素不是集合,也会有一个Count属性。曾经发过专门的帖子表示这一现象:http://www.pstips.net/interesting-count-property-in-powershell-v3.html

  • elale

    抑制错误信息

    函数中的错误信息,也有可能作为返回值的一部分,因为默认这些错误信息会直接输出。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    Function ErrorTest()
    {
    #该进程不存在
    Stop-Process -Name “www.mossfly.com”
    }

    用$r = ErrorTest 测试了一下,发现那些错误信息不会计入返回值$r。

    当然抑制那些错误信息显示还是很有用的。