在PowerShell中正确使用范围变量是什么?

时间:2013-04-01 21:41:37

标签: powershell

我编写代码的方式是我一直在制作单独的ps1文件来执行特定任务。在这样做时,我注意到一个文件中的脚本可以访问调用脚本的变量。

出于我有限的目的,我不认为我会想要全局变量,因为我希望每个ps1文件都充当一个传递所需参数的函数。

我应该为我创建的每个变量定义范围吗?有没有办法强制ps1文件中的所有变量在范围内是本地的?或者我是否需要在每个变量上设置范围?

编辑(未经测试的简化代码演示):

第二个文件将从第一个文件打印$ month。这意味着它是一个全局的而不是本地的file1.ps1。我不想要全局变量,因为我宁愿传递我需要的其他脚本需要的东西。应该将file2.ps定义为防止这种情况的函数吗?

file1.ps1:

$date = Get-Date
$month = $date.Month

./file2.ps1

---------------------
file2.ps1:

write-host $month

=================================

3 个答案:

答案 0 :(得分:2)

除非您将其声明为特定范围,否则将在本地范围内自动创建任何变量。 Script是脚本文件基础中命令的本地范围,函数是函数内部的命令的本地范围。 Global是会话的“本地范围”(例如,命令直接在控制台中编写)。例如:

MyScript.ps1

$myscriptvar = "This is in a local SCRIPT scope"

function test {
    $myfuncvar = "This is in the local scope for the function"
    #I can READ $myscriptvar in here, but if I define it (ex $myscriptvar = 2), 
    #the change will exist in a LOCAL variable ($function:myscriptvar) in the function only.
}

test

控制台

$myglobalvar = @"
This is in the global scope and can be read by 
the script and the function inside the script, but any changes will be saved in 
their local scope if not specified like $global:mygloblvar
"@

.\MyScript.ps1

因此默认情况下,所有变量都在“本地”范围内创建,它只取决于您定义它的位置(在控制台,脚本文件,函数中)。

编辑脚本示例:

Untitled2.ps1

"In script2, `$myvar is: $:myvar"
"In script2, `$script:myvar is: $script:myvar"
$myvar = "lol"

Untitled1.ps1

$myvar = "Hey"
.\Untitled2.ps1
$myvar

控制台

PS > .\Untitled1.ps1
In script2 , $myvar is: Hey
In script2 , $script:myvar is:
Hey

答案 1 :(得分:1)

实际上,我认为你问题最重要的方面还没有得到解决:范围污染。 范围污染是一个非常合理的问题,可能比你的例子更麻烦。请考虑以下两个脚本

=========== script1.ps1 ============
$month = "jan"
$year = "1999"    
. .\script2.ps1    
"Date in script1 is {0}, {1}" -f $month, $year
=========== END script1.ps1 ============

=========== script2.ps1 ============
$year = "2013"
"Date in script2 is {0}, {1}" -f $month, $year
$month = "feb"
=========== END script2.ps1 ============

输出是这样的:

Date in script2 is jan, 2013
Date in script1 is feb, 2013

也就是说,不仅script2 - 假定的“子” - 可以访问script1的变量,而script1 - 假设的“父” - 也可以访问script2的变量!原因是点源脚本不是父子关系;点源实体与点源实体相当。好像脚本是写的

$month = "jan"
$year = "1999"
$year = "2013"
"Date in script2 is {0}, {1}" -f $month, $year
$month = "feb"
"Date in script1 is {0}, {1}" -f $month, $year

您认识到存在范围问题这一事实意味着您至少应该考虑功能和模块以进行适当的封装。如需进一步阅读,请查看我在Simple-Talk.com上的几篇文章:

答案 2 :(得分:0)

一般情况下,默认范围(即没有修饰符)几乎总是足够的,除非你需要用其他范围覆盖它:

  

您在范围中包含的项目在其范围内可见             已创建并在任何子范围内,除非您明确指出             私人的。

如果您创建一个函数,它将拥有自己的作用域。您在函数中声明的任何变量都将限制在该范围内(函数内部)。