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

Mik*_*sen 12 powershell powershell-2.0

当我的shell启动时,我加载了一个外部脚本,它有一些我用来测试的东西.就像是:

# Include Service Test Tools
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
. $scriptPath\SvcTest.ps1
Run Code Online (Sandbox Code Playgroud)

SvcTest.ps1,我有两个功能:

function isURI ([string] $address)
{
   ($address -as [System.URI]).AbsoluteURI -ne $null
}
Run Code Online (Sandbox Code Playgroud)

以及:

function Test-Service ([string] $url)
{
   if (-Not (isURI($url)))
   {
      Write-Host "Invalid URL: $url"
      return
   }

   # Blah blah blah, implementation not important
}
Run Code Online (Sandbox Code Playgroud)

isURI函数基本上只是一个实用程序函数,它允许Test-Service并且可能还有其他函数验证URI.但是,当我启动shell时,我看到这isURI是一个全局加载的函数.我甚isURI http://www.google.com至可以从命令行输入并返回True.

我的问题:有没有办法让isURI 私有,所以只有内部的功能SvcTest.ps1可以使用它,同时仍然允许Test-Service全球?基本上,我正在寻找一种在PowerShell脚本中使用属性封装的方法.

Adi*_*bar 13

实际上,如果调用.ps1文件,默认情况下,在其中声明的任何函数和变量都在脚本中私有地限定(这称为"脚本范围").既然你看到全局定义了这两个函数,我推断你是点源 SvcTest.ps1,即调用它就像这样

PS> . <path>\SvcTest.ps1
Run Code Online (Sandbox Code Playgroud)

而不是像这样称呼

PS> <path>\SvcTest.ps1
Run Code Online (Sandbox Code Playgroud)


你有两个选择.

1.如果您的私有函数仅由脚本中的另一个函数使用,则可以在使用它的函数体内声明私有函数,并通过点源来调用脚本:

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
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

在任何一种情况下,Test-Service都将在全局范围内定义,而isURI将仅限于脚本范围.


*可能会使问题混淆的一件事是,PowerShell只查找路径中的可执行文件,而不是当前工作目录,除非.已添加到路径中(默认情况下不是这种情况).因此,在PowerShell中调用工作目录中的脚本以在脚本名称之前.\.不要将.表示工作目录的信息与点源操作符混淆.这会调用脚本:

PS> .\SvcTest.ps1
Run Code Online (Sandbox Code Playgroud)

这点来源:

PS> . .\SvcTest.ps1
Run Code Online (Sandbox Code Playgroud)

  • 第二个选项不起作用!如果没有点源,内部函数就无法运行。在 powershell v5 和 v7 上测试:`PS&gt; .\SvcTest.ps1` `PS&gt; Test-Service "http://web.com"` `isURI:术语“isURI”不被识别为 cmdlet 的名称,函数、脚本文件或可运行程序。` (3认同)

Bil*_*art 6

在我看来,您是在要求通过创建模块来获得可用的功能。

模块允许您封装代码并仅导出所需的别名和/或函数。模块清单不是严格要求的;如果不使用清单,则可以使用Export-ModuleMember指定要从模块导出的成员。

有关help about_Modules更多信息,请参阅关于主题。


Knu*_*ger 5

如果你想为你的函数使用私有作用域,可以在 Powershell 中像这样完成。

function Private:isURI ([string] $address)
{
   ($address -as [System.URI]).AbsoluteURI -ne $null
}
Run Code Online (Sandbox Code Playgroud)