Kev*_*han 61 powershell powershell-1.0
我希望能够告诉我执行脚本的运行路径.
这往往不是$ pwd.
我需要调用相对于我的脚本的文件夹结构中的其他脚本,虽然我可以对路径进行硬编码,但是当尝试从"开发"升级到"测试"时,这既令人反感又有点痛苦"生产".
Mic*_*ens 99
最初由PowerShell团队的Jeffrey Snover发布的无处不在的脚本(Skyler的答案中给出)以及Keith Cedirc和EBGreen发布的变体都有严重的缺点 - 代码是否报告您所期望的取决于您所称的位置!
我的代码通过简单地引用脚本范围而不是父范围来克服这个问题:
function Get-ScriptDirectory
{
Split-Path $script:MyInvocation.MyCommand.Path
}
Run Code Online (Sandbox Code Playgroud)
为了说明这个问题,我创建了一个测试工具,以四种不同的方式评估目标表达.(括号内的术语是以下结果表的关键.)
最后两列显示了使用脚本范围(即$ script :)或父范围(使用-scope 1)的结果."脚本"的结果意味着调用正确地报告了脚本的位置."模块"结果表示调用报告了包含函数的模块的位置,而不是调用函数的脚本; 这表明这两个函数的缺点是您无法将该函数放入模块中.
除了表中的显着观察之外,设置模块问题是使用父范围方法在大多数情况下失败(事实上,成功的频率是其成功的两倍).

最后,这是测试车辆:
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
Run Code Online (Sandbox Code Playgroud)
ScriptDirFinder.ps1的内容:
function Get-ScriptDirectory2
{
Split-Path $script:MyInvocation.MyCommand.Path
# $Invocation = (Get-Variable MyInvocation -Scope 1).Value
# Split-Path $Invocation.MyCommand.Path
}
Run Code Online (Sandbox Code Playgroud)
ScriptDirFinder.psm1的内容:
function Get-ScriptDirectory3
{
Split-Path $script:MyInvocation.MyCommand.Path
# $Invocation = (Get-Variable MyInvocation -Scope 1).Value
# Split-Path $Invocation.MyCommand.Path
}
Run Code Online (Sandbox Code Playgroud)
我不熟悉PowerShell 2中引入的内容,但很可能在Jeffhell Snover发布他的示例时,PowerShell 1中不存在脚本范围.
当我发现他的代码示例在网络上广泛扩散时,我感到很惊讶,当我尝试它时它立即失败了!但那是因为我使用它的方式不同于Snover的例子(我不是在脚本顶部而是从另一个函数内部调用它(我的"嵌套两次"示例).)
2011.09.12更新
您可以在我刚刚发布的关于Simple-Talk.com的文章中的模块上阅读有关此内容的其他提示和技巧: 进一步了解Rabbit Hole:PowerShell模块和封装.
Mic*_*ley 21
你标记你的问题PowerShell的1.0版本,但是,如果你有机会到PowerShell的3.0版本,你知道有$PSCommandPath和$PSScriptRoot这使得越来越脚本路径变得更容易一些.有关更多信息,请参阅本页的"其他脚本功能"部分.
Kei*_*ill 11
我们在大多数脚本中使用这样的代码已经好几年没有问题了:
#--------------------------------------------------------------------
# Dot source support scripts
#--------------------------------------------------------------------
$ScriptPath = $MyInvocation.MyCommand.Path
$ScriptDir = Split-Path -Parent $ScriptPath
. $ScriptDir\BuildVars.ps1
. $ScriptDir\LibraryBuildUtils.ps1
. $ScriptDir\BuildReportUtils.ps1
Run Code Online (Sandbox Code Playgroud)
我最近遇到了同样的问题.以下文章帮助我解决了这个问题:http://blogs.msdn.com/powershell/archive/2007/06/19/get-scriptdirectory.aspx
如果您对它的工作原理不感兴趣,请参阅本文所需的所有代码:
function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
Split-Path $Invocation.MyCommand.Path
}
Run Code Online (Sandbox Code Playgroud)
然后,您只需执行以下操作即可获得路径:
$path = Get-ScriptDirectory
Run Code Online (Sandbox Code Playgroud)
我认为你可以找到运行脚本的路径
$MyInvocation.MyCommand.Path
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你 !
塞德里克
| 归档时间: |
|
| 查看次数: |
80545 次 |
| 最近记录: |