Windows Powershell 变量的作用域
如果我们对变量不做特别的声明,Powershell解释器会自动处理和限制变量的作用域。将下面的内容命令保存着至test1.ps1
$windows=$env:windir “WindowsFolder:$windows”
然后在控制台给变量$windows赋值,并调用Test.ps1脚本。
PS>$windows="Hellow" PS>.\test.ps1 WindowsFolder:C:\Windows PS>$windows Hellow
调用脚本时,会分配一个变量$windows,在脚本调用结束后,这个变量被回收,脚本中的变量不会影响脚本外的变量,因为它们在不同的作用域中。powershell会针对每个函数和脚本给它们分配不同的作用域。
更改变量的可见性
你可以很容易的看到没有Powershell解释器自动限制可见性时会发生什么状况,同样是刚才的脚本,刚才的命令,只是在运行脚本时多加上一个点”.”和一个空格:
PS>$windows="Hellow" PS>..\test.ps1 WindowsFolder:C:\Windows PS>$windows C:Windows
在运行脚本时使用一个原点和空格,Powershell解释器就不会为脚本本身创建自己的变量作用域,它会共享当前控制台的作用域,这种不太灵活但却简单的方法,使用时一定要格外小心。
加强变量可见性限制的优点:清空初始化环境
可以假设一个场景,如果你在当前控制台不小心定义了一个只读的常量,这个常量既不能更新也不能删除,很是麻烦。但是如果你在脚本中操作这个变量就不成问题,因为脚本有自己的作用域。例如,将下面文本保存为test.ps1,并调用没有任何问题:
New-Variablea-value1-optionConstant "Value:$a"PS>.\test.ps1 Value:1 PS>.\test.ps1 Value:1
但是如果你通过圆点禁用作用域限制,调用test.ps1,就会有异常,因为一个常量不能被创建两次。
PS>..\test.ps1 Value:1 PS>..\test.ps1 New-Variable:Avariablewithname'a'alreadyexists. Attest.ps1:1char:13 +New-Variable<<<<a-value1-optionConstant +CategoryInfo:ResourceExists:(a:String)[New-Variable],SessionStateException +FullyQualifiedErrorId:VariableAlreadyExists,Microsoft.PowerShell.Commands.NewVariableCommand
所以这种变量的作用域限制可以把变量的冲突降到最小。
设置单个变量的作用域
到目前为止,看到的变量作用域的改变都是全局的,能不能针对某个具体变量的作用域做一些个性化的设置。
$global
全局变量,在所有的作用域中有效,如果你在脚本或者函数中设置了全局变量,即使脚本和函数都运行结束,这个变量也任然有效。
$script
脚本变量,只会在脚本内部有效,包括脚本中的函数,一旦脚本运行结束,这个变量就会被回收。
$private
私有变量,只会在当前作用域有效,不能贯穿到其他作用域。
$local
默认变量,可以省略修饰符,在当前作用域有效,其它作用域只对它有只读权限。
打开Powershell控制台后,Powershell会自动生成一个新的全局作用域。如果增加了函数和脚本,或者特殊的定义,才会生成其它作用域。在当前控制台,只存在一个作用域,通过修饰符访问,其实访问的是同一个变量:
PS>$logo="www.nhooo.com" PS>$logo www.nhooo.com PS>$private:logo www.nhooo.com PS>$script:logo www.nhooo.com PS>$private:logo www.nhooo.com PS>$global:logo www.nhooo.com
当调用一个已定义的函数,Powershell会生成第二个作用域,它可以对调用者的作用域中的变量执行读操作,但是不能执行写操作。
PS>functionf(){"var=$var";$var="functioninner";$var} PS>$var="Iaminconsole." PS>$var Iaminconsole. PS>f var=Iaminconsole. functioninner PS>$var Iaminconsole.
怎样把当前控制台中的变量保护起来,不让它在函数和脚本中被访问,Private修饰符就派上了用场。
PS>functionf(){"var=$var";$var="functioninner";$var} PS>$private:var="iamaprivatevariableinconsole,otherscopecannotaccessme." PS>f var= functioninner PS>$private:var iamaprivatevariableinconsole,otherscopecannotaccessme.
对于$private限制的变量能不能在函数中通过$global修改呢?不但不能修改,还会删除当前的$private变量
PS>Functionf(){"var=$var";$global:var="Trytochangevariableinfunction"} PS>$private:var="Iamaprivatevariable" PS>$private:var Iamaprivatevariable PS>$var Iamaprivatevariable PS>f var= PS>$private:var PS>$var PS> PS>$private-eq$null True
但是$local修饰的变量则可以通过$global在函数内部更改。
PS>Functionf(){"var=$var";$global:var="Trytochangevariableinfunction"} PS>$var="Iamalocalvariable." PS>$var Iamalocalvariable. PS>$private:var Iamalocalvariable. PS>f var=Iamalocalvariable. PS>$var Trytochangevariableinfunction PS>$local:var Trytochangevariableinfunction