2

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

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

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

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

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

file1.ps1:

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

./file2.ps1

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

write-host $month

=================================
4

3 回答 3

2

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

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

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

使用脚本编辑示例:

无标题2.ps1

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

无标题1.ps1

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

安慰

PS > .\Untitled1.ps1
In script2 , $myvar is: Hey
In script2 , $script:myvar is:
Hey
于 2013-04-01T21:55:19.640 回答
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 的变量!原因是 dot-sourcing 脚本不是父子关系;点源实体与点源实体相当。就好像剧本写的一样

$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 上的几篇文章:

于 2013-04-02T14:37:05.187 回答
0

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

您包含在范围中的项目在创建它的范围和任何子范围中都是可见的,除非您明确将其设为私有。

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

于 2013-04-01T21:45:12.047 回答