gpt4 book ai didi

powershell - 如何找到正在执行的脚本的源路径?

转载 作者:行者123 更新时间:2023-12-03 05:40:13 25 4
gpt4 key购买 nike

我希望能够知道我的执行脚本是从哪个路径运行的。
这通常不是 $pwd。

我需要调用与我的脚本相关的文件夹结构中的其他脚本,虽然我可以对路径进行硬编码,但在尝试从“dev”升级为“时,这既令人厌恶又有点麻烦”测试”到“生产”。

最佳答案

无处不在的脚本最初由 Jeffrey Snover 发布PowerShell 团队的版本(在 Skyler's answer 中给出)以及 Keith Cedirc 和 EBGreen 发布的变体都存在一个严重的缺陷 -代码是否报告您期望的内容取决于您调用它的位置!

下面的代码通过简单地引用脚本范围而不是范围来解决这个问题:

function Get-ScriptDirectory
{
Split-Path $script:MyInvocation.MyCommand.Path
}

为了说明问题,我创建了一个测试工具,它以四种不同的方式评估目标表达式。 (括号内的术语是下面结果表的关键。)

  1. 内联代码[内联]
  2. 内联函数,即主程序中的函数[内联函数]
  3. 点源函数,即将同一函数移至单独的 .ps1 文件 [点源]
  4. 模块函数,即移动到单独的 .psm1 文件 [模块] 的相同函数

最后两列显示使用脚本作用域(即 $script:)或使用父作用域(使用 -scope 1)的结果。 “script”的结果意味着调用正确地报告了脚本的位置。 “模块”结果意味着调用报告了包含该函数的模块的位置,而不是调用该函数的脚本;这表明这两个函数都有一个缺点,即您不能将函数放入模块中。

将模块问题放在一边,从表中观察到的一个值得注意的现象是,使用父作用域方法在大多数情况下都会失败(事实上,成功的频率是其成功的两倍)。

table of input combinations

最后,这是测试车辆:

function DoubleNested()
{
"=== DOUBLE NESTED ==="
NestCall
}

function NestCall()
{
"=== NESTED ==="
"top level:"
Split-Path $script:MyInvocation.MyCommand.Path
#$foo = (Get-Variable MyInvocation -Scope 1).Value
#Split-Path $foo.MyCommand.Path
"immediate func call"
Get-ScriptDirectory1
"dot-source call"
Get-ScriptDirectory2
"module call"
Get-ScriptDirectory3
}

function Get-ScriptDirectory1
{
Split-Path $script:MyInvocation.MyCommand.Path
# $Invocation = (Get-Variable MyInvocation -Scope 1).Value
# Split-Path $Invocation.MyCommand.Path
}

. .\ScriptDirFinder.ps1
Import-Module ScriptDirFinder -force

"top level:"
Split-Path $script:MyInvocation.MyCommand.Path
#$foo = (Get-Variable MyInvocation -Scope 1).Value
#Split-Path $foo.MyCommand.Path

"immediate func call"
Get-ScriptDirectory1
"dot-source call"
Get-ScriptDirectory2
"module call"
Get-ScriptDirectory3

NestCall
DoubleNested

ScriptDirFinder.ps1 的内容:

function Get-ScriptDirectory2
{
Split-Path $script:MyInvocation.MyCommand.Path
# $Invocation = (Get-Variable MyInvocation -Scope 1).Value
# Split-Path $Invocation.MyCommand.Path
}

ScriptDirFinder.psm1 的内容:

function Get-ScriptDirectory3
{
Split-Path $script:MyInvocation.MyCommand.Path
# $Invocation = (Get-Variable MyInvocation -Scope 1).Value
# Split-Path $Invocation.MyCommand.Path
}

我不熟悉 PowerShell 2 中引入的内容,但很可能在 Jeffrey Snover 发布他的示例时,PowerShell 1 中不存在脚本作用域。

令我惊讶的是,虽然我发现他的代码示例在网络上广泛传播,但当我尝试时它立即失败了!但这是因为我使用它的方式与 Snover 的示例不同(我不是在脚本顶部调用它,而是从另一个函数内部调用它(我的“嵌套两次”示例)。)

2011.09.12更新

您可以在我刚刚在 Simple-Talk.com 上发表的文章中阅读有关模块的其他提示和技巧: Further Down the Rabbit Hole: PowerShell Modules and Encapsulation .

关于powershell - 如何找到正在执行的脚本的源路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/801967/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com