2015-03-02 108 views
0

我试图了解变量如何保留值和范围。为此我创建了两个简单的脚本。了解PowerShell变量范围

低级别的脚本看起来像这样

param(
    $anumber=0 
) 

function PrintNumber 
{ 
    Write-Host "Number is $anumber" 
    $anumber++ 
    Write-Host "Number is now $anumber" 
} 

顶层脚本看起来像这样

$scriptPath=(Split-Path -parent $PSCommandPath)+"\" + "calledscript.ps1" 
#dot source the called script 
. $scriptPath 22 

for($i=0;$i -lt 10;$i++) 
{ 
    PrintNumber 
} 

主脚本“点源”被调用的脚本一次,在一开始并传递一个值,“22”。然后我从顶层脚本中调用PrintNumber函数10次。我想输出会是什么样子:

号是22 人数现已23

号是23 号是现在24

号是现在24 号是25

而是调用该函数时该数字始终为22,(如下所示)。为什么这个数字每次重新设置为22,即使我只拉了点源脚本一次,并将数字初始化为22?

号是22 人数现已23

号是22 号是现在23

号是22 号是现在23

感谢

(请忽略任何错别字)

+0

如果将其定义更改为'$ global:anumber',会发生什么情况? – arco444 2015-03-02 12:02:29

+0

我将参考(不是声明)从$ anumber ++更改为$ global:an ++ ++,然后按我的预期递增。不完全确定为什么真的! – Keith 2015-03-02 13:52:13

+0

绝对是一个范围界定问题。我不深入了解很多,但在PowerShell中有'local','script'和'global'变量。有意义的是,由于您从其他脚本获取变量,所以默认范围是'script',并且递增的值不会持续。 – arco444 2015-03-02 14:11:14

回答

0

这是因为变量继承。 Technet是这样解释的。

A child scope does not inherit the variables, aliases, and functions from 
the parent scope. Unless an item is private, the child scope can view the 
items in the parent scope. And, it can change the items by explicitly 
specifying the parent scope, but the items are not part of the child scope. 

由于脚本是点源的,它会创建一个本地会话的变量。当函数访问具有相同名称的变量时,它可以从父作用域读取该变量,但随后会创建一个本地副本,然后将其增量并随后销毁。

+0

感谢@JonC,但是什么变量是从父范围读取的函数?我只在被调用的脚本中有变量,而不是父变量。 – Keith 2015-03-02 13:39:18

+0

另一个问题是,如何显式指定父范围? – Keith 2015-03-02 13:53:25

+0

https://technet.microsoft.com/en-us/library/hh847849.aspx涵盖范围的基础知识。简短的答案是使用像$ global:anumber或$ script:anumber这样的修饰符。您还可以使用cmdlets的相对修饰符,如'get-variable -name anumber -scope 0',其中0是当前作用域,1是直接父对象,2是下一个父对象等等。 – JonC 2015-03-02 14:22:44