当我的shell启动时,我加载了一个外部脚本,它有一些我用来测试的东西。类似的东西:
# Include Service Test Tools
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
. $scriptPath\SvcTest.ps1
在SvcTest.ps1
中,我有两个功能:
function isURI ([string] $address)
{
($address -as [System.URI]).AbsoluteURI -ne $null
}
以及:
function Test-Service ([string] $url)
{
if (-Not (isURI($url)))
{
Write-Host "Invalid URL: $url"
return
}
# Blah blah blah, implementation not important
}
isURI
函数基本上只是一个实用函数,它允许Test-Service
并且可能还有其他函数验证URI。但是,当我启动shell时,我发现isURI
是一个全局加载的函数。我甚至可以从命令行键入isURI http://www.google.com
并返回True
。
我的问题:有没有办法让isURI
私有,这样只有SvcTest.ps1
内的功能才能使用它,同时仍然允许Test-Service
要全球化吗?基本上,我正在寻找一种在PowerShell脚本中使用属性封装的方法。
答案 0 :(得分:12)
实际上,如果你调用.ps1文件,默认情况下 在其中声明的任何函数和变量都是在脚本中私有地限定的(这被称为"脚本范围&#34 )。由于您看到全局定义了这两个功能,因此我推断您已经点源 SvcTest.ps1 ,即按此调用
PS> . <path>\SvcTest.ps1
而非调用就像这样
PS> <path>\SvcTest.ps1
你有两个选择。
1。如果您的私有函数仅由脚本中的另一个函数使用,则可以在使用它的函数体内声明私有函数,并通过dot-调用脚本采购它:
function Test-Service ([string] $url)
{
function isURI ([string] $address)
{
($address -as [System.URI]).AbsoluteURI -ne $null
}
if (-Not (isURI($url)))
{
Write-Host "Invalid URL: $url"
return
}
# Blah blah blah, implementation not important
}
2. 如果脚本中的多个其他函数需要私有函数(或者即使不是,这是上面的替代函数),为任何函数显式声明全局作用域你想要全局定义,然后调用脚本而不是点源:
function isURI ([string] $address)
{
($address -as [System.URI]).AbsoluteURI -ne $null
}
function global:Test-Service ([string] $url)
{
if (-Not (isURI($url)))
{
Write-Host "Invalid URL: $url"
return
}
# Blah blah blah, implementation not important
}
在任何一种情况下,测试服务都将在全局范围内定义,而 isURI 将仅限于脚本范围。
<小时/> *可能会让问题混淆的一件事是,PowerShell只查找路径中的可执行文件,而不是当前工作目录,除非.
已添加到路径中(默认情况下不是这种情况) 。因此,在PowerShell中调用工作目录中的脚本以在脚本名称前面加.\
时,这是典型的。不要将代表工作目录的.
与点源操作员混淆。这会调用脚本:
PS> .\SvcTest.ps1
这点来源:
PS> . .\SvcTest.ps1
答案 1 :(得分:2)
如果你想为你的函数使用私有作用域,可以在Powershell中这样做。
function Private:isURI ([string] $address)
{
($address -as [System.URI]).AbsoluteURI -ne $null
}
答案 2 :(得分:2)
听起来像是你要求通过创建模块提供的功能。
模块允许您封装代码并仅导出所需的别名和/或函数。模块清单不是严格要求的;如果您不使用清单,则可以使用Export-ModuleMember
指定要从模块导出的成员。
有关详细信息,请参阅help about_Modules
主题。
答案 3 :(得分:0)
您是否尝试将isURI函数移动为脚本,然后在其他函数中进行点源而不是将其作为函数运行?
isuri.ps1:
Param([string] $address)
($address -as [System.URI]).AbsoluteURI -ne $null
svctext.ps1:
function Test-Service ([string] $url)
{
if (-Not (. .\isURI($url)))
{
Write-Host "Invalid URL: $url"
return
}
# Blah blah blah, implementation not important
}