变量 用于存储 值 。你可以将变量理解为数字盒。如果想多次使用某个值,就可以将该值放入盒中。假如需要在代码中重复使用一个数,可以将这个数存入变量,以便在需要使用该数的地方调用变量,而无须一次次输入同一个数。不过,从“变量”这个名称或许可以猜出,变量真正强大的功能是其可变性:放入盒中的值可以进行替换,或者取出,展示之后再放回。
后文将介绍,利用变量的可变性构建出的代码适用于一般情况,而不是针对特定场景写“死”的。本节将介绍使用变量的基本方式。
在PowerShell中,变量以美元符号(
$
)开头。见到美元符号,PowerShell便知道调用的是变量,而不是cmdlet、函数、脚本文件或可执行文件。如果想显示
MaximumHistoryCount
变量的值,那么需要在前面加上美元符号,然后再调用,如代码清单2-1所示。
代码清单2-1
调用
$MaximumHistoryCount
变量
PS> $MaximumHistoryCount
4096
$MaximumHistoryCount
是一个内置变量,指明了PowerShell在命令历史中最多存储多少个命令,默认为4096个。
如果想修改变量的值,则需要先输入变量的名称(以美元符号开头),然后输入等号(
=
)和新值,如代码清单2-2所示。
代码清单2-2
修改
$MaximumHistoryCount
变量的值
PS> $MaximumHistoryCount = 200
PS> $MaximumHistoryCount
200
这里将
$MaximumHistoryCount
变量的值改成了
200
,即PowerShell在命令历史中只存储前200个命令。
代码清单2-1和代码清单2-2使用的变量都已经存在。在PowerShell中,变量分为两大类:一是 用户定义的变量 ,即由用户创建的变量;二是 自动变量 ,即PowerShell自带的变量。先来看用户定义的变量。
变量在使用前要先存在。可以在PowerShell控制台中输入
$color
试试,如代码清单2-3所示。
代码清单2-3 输入未定义的变量将报错
PS> $color
The variable '$color' cannot be retrieved because it has not been set.
At line:1 char:1
+ $color
+ ~~~~
+ CategoryInfo : InvalidOperation: (color:String) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined
启用严格模式
如果没有看到代码清单2-3中的错误,并且控制台什么也没输出,那么请执行下列命令来启用严格模式。
PS> Set-StrictMode -Version Latest
启用严格模式后,倘若违背良好的编程实践,PowerShell将抛出错误。例如,在严格模式下,如果引用不存在的对象属性或未定义的变量,PowerShell将返回错误。编写脚本时,建议启用严格模式,这是最佳实践,有助于迫使我们编写更为简洁、结果更可预期的代码。如果只是在PowerShell控制台中运行交互式代码,那么一般不启用该模式。关于严格模式的更多信息,可以执行
Get-Help Set-StrictMode -Examples
命令来查看。
在代码清单2-3中,我们试图引用尚不存在的
$color
变量,并得到错误。如果想创建变量,那么需要先声明(宣告变量存在),然后再
赋值
(或称作
初始化
)。这两步可以合二为一,如代码清单2-4所示,创建一个名为
$color
的变量,并将其值设为
blue
。为变量赋值的方法与前文修改
$MaximumHistoryCount
变量的值一样,即先输入变量的名称,然后再输入一个等号和值。
代码清单2-4
创建
$color
变量,并将值设为
blue
PS> $color = 'blue'
创建变量并为其赋值之后,便可以在控制台中输入变量的名称,以引用变量,如代码清单2-5所示。
代码清单2-5 查看变量的值
PS> $color
blue
变量的值会保持不变,除非有人修改。
$color
变量可以随意调用,调用多少次都行,而且始终返回
blue
值,除非该变量被重新定义了。
使用等号定义变量时(参见代码清单2-4),作用与
Set-Variable
命令一样。同样,在控制台中输入变量,查看变量的值(参见代码清单2-5),作用与
Get-Variable
命令一样。代码清单2-6使用这两个命令重新实现了代码清单2-4和代码清单2-5中的操作。
代码清单2-6
用
Set-Variable
命令创建一个变量,再使用
Get-Variable
命令显示该变量的值
PS> Set-Variable -Name color -Value blue
PS> Get-Variable -Name color
Name Value
---- -----
color blue
Get-Variable
命令还可以返回所有可用的变量,如代码清单2-7所示。
代码清单2-7
用
Get-Variable
命令返回所有变量
PS> Get-Variable
Name Value
---- -----
$ Get-PSDrive
? True
^ Get-PSDrive
args {}
color blue
--snip--
这个命令会列出内存中当前可用的全部变量。注意,其中一些变量不是我们定义的。下一节将介绍这种变量。
前文介绍过自动变量,即PowerShell自带的变量。虽然PowerShell允许我们修改某些自动变量(参见代码清单2-2),但我通常不建议这么做,因为这有可能导致意想不到的结果。一般来说,应该将自动变量视作
只读
的。(建议现在将
$MaximumHistoryCount
的值改回4096!)
本节将介绍几个常用的自动变量:
$null
、
$LASTEXITCODE
以及偏好设置变量。
$null
变量
$null
变量比较特殊,即代表空值。将
$null
赋值给变量表示只创建该变量,但不赋予具体的值,如代码清单2-8所示。
代码清单2-8
为变量赋值
$null
PS> $foo = $null
PS> $foo
PS> $bar
The variable '$bar' cannot be retrieved because it has not been set.
At line:1 char:1
+ $bar
+ ~~~~
+ CategoryInfo : InvalidOperation: (bar:String) [], RuntimeException
+ FullyQualifiedErrorId : VariableIsUndefined
这里将
$null
赋给
$foo
变量。随后调用
$foo
时什么也没有显示,而且没有报错,因为PowerShell能识别该变量。
如果想判断PowerShell是否能识别某个变量,可以将变量的名称通过参数传给
Get-Variable
命令。从代码清单2-9可以看出,PowerShell知道
$foo
变量是存在的,但不能识别
$bar
变量。
代码清单2-9
用
Get-Variable
命令查找变量
PS> Get-Variable -Name foo Name Value ---- ----- foo PS> Get-Variable -Name bar Get-Variable : Cannot find a variable with the name 'bar'. At line:1 char:1 + Get-Variable -Name bar + ~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (bar:String) [Get-Variable], ItemNotFoundException + FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.GetVariableCommand
你可能觉得奇怪,为什么要多此一举地将变量的值定义为
$null
呢?其实,
$null
非常有用。例如,本章后文将介绍,变量的值经常作为某种响应,比如函数的输出。经检查,如果变量的值仍是
$null
,那么便知道函数中有地方出错了,并可以据此做出相应处理。
$LASTEXITCODE
变量
另一个常用的自动变量是
$LASTEXITCODE
。PowerShell允许调用外部可执行程序,比如旧时测试网站响应的ping.exe。外部程序运行结束后会返回一个
退出码
(或称作
返回码
),以表示一种状态。通常,0表示成功,其他数则表示失败或其他异常。对ping.exe程序来说,0表示成功ping通一个节点,1则表示无法ping通。
运行ping.exe时,你只能看到预期的输出,而看不到退出码,如代码清单2-10所示。这是因为退出码隐藏在
$LASTEXITCODE
变量中。
$LASTEXITCODE
变量的值始终是最后执行那个程序的退出码。代码清单2-10先ping google.com,返回了一个退出码,然后又ping一个不存在的域名,也返回了一个退出码。
代码清单2-10
用ping.exe演示
$LASTEXITCODE
变量
PS> ping.exe -n 1 dfdfdfdfd.com
Pinging dfdfdfdfd.com [14.63.216.242] with 32 bytes of data:
Request timed out.
Ping statistics for 14.63.216.242:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
PS> $LASTEXITCODE
1
PS> ping.exe -n 1 google.com
Pinging google.com [2607:f8b0:4004:80c::200e] with 32 bytes of data:
Reply from 2607:f8b0:4004:80c::200e: time=47ms
Ping statistics for 2607:f8b0:4004:80c::200e:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 47ms, Maximum = 47ms, Average = 47ms
PS> $LASTEXITCODE
0
ping google.com时,
$LASTEXITCODE
的值是0,而ping虚构的域名dfdfdfdfd.com时,值为1。
PowerShell中有一类称为
偏好设置变量
的自动变量。这类变量用于控制各种输出流的默认行为,包括
Error
、
Warning
、
Verbose
、
Debug
和
Information
。
如果想找出所有偏好设置变量,可以使用
Get-Variable
命令,并指定筛选出名称以“Preference”结尾的变量,如下所示。
PS> Get-Variable -Name *Preference Name Value ---- ----- ConfirmPreference High DebugPreference SilentlyContinue ErrorActionPreference Continue InformationPreference SilentlyContinue ProgressPreference Continue VerbosePreference SilentlyContinue WarningPreference Continue WhatIfPreference False
这些变量可用于配置PowerShell的各种输出类型。例如,犯错时看到的红色文本是
Error
输出流。输入下列命令就可以看到这样的错误消息。
PS> Get-Variable -Name 'doesnotexist'
Get-Variable : Cannot find a variable with the name 'doesnotexist'.
At line:1 char:1
+ Get-Variable -Name 'doesnotexist'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (doesnotexist:String) [Get-Variable],
ItemNotFoundException
+ FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.GetVariableCommand
你应该会看到类似的错误消息,因为这是
Error
流的默认行为。如果出于某种原因,不想看到错误文本,想要出错时静默就好,那么可以将
$ErrorActionPreference
变量的值设为
SilentlyContinue
或
Ignore
,这样PowerShell就不会输出任何错误文本了。
PS> $ErrorActionPreference = 'SilentlyContinue'
PS> Get-Variable -Name 'doesnotexist'
PS>
可以看到,没有输出任何错误文本。通常忽略错误并不是好的做法。继续阅读前,请将
$ErrorActionPreference
的值改回
Continue
。关于偏好设置变量的更多信息,可以执行
Get-Help about_Preference_Variables
命令来查看关于主题中的内容。