【问题标题】:Include relative files in PowerShell在 PowerShell 中包含相关文件
【发布时间】:2010-10-15 14:45:15
【问题描述】:

我想包含具有这种伪语法的脚本文件:

Include '.\scripA.ps1'

但我发现的唯一东西是这样的:

$thisScript = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
. ($thisScript + '.\scriptA.ps1')

那是丑陋的。

是否有一些不错的方法来包含具有相对路径的脚本?

【问题讨论】:

    标签: powershell include relative-path


    【解决方案1】:

    您可以使用 $PSScriptRoot 和“Split-Path”指令使其干净地用于相对路径。 . (($PSScriptRoot | Split-Path | Split-Path)+'somedir\ps\script.ps1')

    【讨论】:

      【解决方案2】:

      这可能适用于任何目录,但如果您的起始目录不是您尝试包含的文件的直接先前目录,它将是一个 slooooooowwwww 查找。 IOW,如果您的搜索起点是 c:\ 或其他驱动器号的根目录,那么这可能会非常慢。

      。 $(Resolve-Path -literal $(gci -Recurse include.ps1))

      如果您在 PC 上开发脚本但需要将它们部署到将脚本作为计划任务运行的服务器,这将特别有效。

      【讨论】:

        【解决方案3】:

        您可以像这样使用 $PSScriptRoot 参数:

        . "$PSScriptRoot\script.ps1"
        

        【讨论】:

        • 我发现这对 Azure ARM 模板 VM CustomScriptExtension 非常有用,我使用 FileUris 参数从存储帐户 blob 容器下载多个文件,然后调用一个引用其他文件的文件。 Azure 文档在如何确定下载文件的相对路径方面不是很有帮助。我正在尝试. .\path\to\script.ps1,当您从 Windows 资源管理器或同一文件夹中的 PS 终端运行脚本时,它可以工作,但它在部署到 Azure 时一直失败。这个答案完全解决了问题。
        【解决方案4】:

        从 V2 开始(从 Win7/2008R2 开始原生;参见 $psversiontable.psversion),您可以轻松地包含如下文件:

        . "RelativeOrAbsolutePathToFile\include.ps1"
        
        $result = FunctionInIncludeFile()
        

        参考:
        How to reuse windows powershell functions in scripts

        【讨论】:

        • 据我所知,问题在于 dot-source 行是相对于当前工作目录进行评估的,而不是相对于包含 dot-source 行的脚本。因此,如果您首先 cd 到包含脚本的目录,则它可以工作,但如果您从另一个目录调用它,则不会。
        • 这可能是设计使然,感谢您的评论,尽管队友!
        【解决方案5】:

        如前所述,点源是最简单的选择,虽然不是特别漂亮。然而,这种格式让它更简洁一点:

        $ScriptDirectory = Split-Path $MyInvocation.MyCommand.Path
        . (Join-Path $ScriptDirectory ScriptA.ps1)
        

        另外,关于相对路径的注释有助于明确说明:原始帖子似乎暗示想要相对于当前工作目录的路径;实际上,其意图是相对于当前脚本的源目录(正如 alex2k8 自己的代码示例所示)。因此,这允许当前脚本访问同一存储库中的其他脚本。

        【讨论】:

          【解决方案6】:

          您可以点源(包含)文件:

          。 .\scriptA.ps1

          获取脚本的完整路径:

          解析路径 .\scriptA.ps1

          【讨论】:

          • 第一部分确实...但是 Resolve-Path 将检查当前目录和您的文件路径。如果你的脚本目录在你的路径中($env:path),它会找到它。
          • 谢谢伙计们,我应该提到治疗地点。
          • 为我工作。谢谢+1
          【解决方案7】:

          很遗憾没有,没有什么好办法。 PowerShell 在 V1 中并没有真正很好地支持这个想法。确实,您正在采取的方法是最好的方法

          【讨论】:

          • v2 是什么?我应该将模块用于外部脚本和“Import-Module ./foo.psm1”语法吗?或者对包含常规脚本的任何改进?
          • @alex2k8,我还没有在 V2 上做太多工作,所以我不能提供太多帮助。我知道模块应该比脚本更加孤立,但除此之外我没有太多数据。
          • 在 v2 中,您可以使用带有清单的模块,该清单定义了所有模块、脚本甚至管理单元/程序集。这样做的一个好处是您可以拥有模块私有的函数和变量。
          • 注意:从 V2 开始,您可以轻松引用包含文件,请参阅下面的答案。
          • 在 PowerShell 3.0 中,您可以使用 . (Join-Path $PSScriptRoot settings.ps1)(以点开头的命令)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-11-10
          • 2011-07-20
          • 2015-11-08
          • 1970-01-01
          • 2017-09-24
          • 2023-04-02
          • 2012-06-08
          相关资源
          最近更新 更多