有没有办法在PowerShell脚本中使某些功能“私有”?

时间:2014-08-04 17:02:38

标签: powershell powershell-v2.0

当我的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脚本中使用属性封装的方法。

4 个答案:

答案 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
}