如何找到正在执行的脚本的源路径? [英] How can I find the source path of an executing script?

查看:34
本文介绍了如何找到正在执行的脚本的源路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道我的执行脚本是从哪个路径运行的.
这通常不是 $pwd.

我需要调用与我的脚本相关的文件夹结构中的其他脚本,虽然我可以对路径进行硬编码,但在尝试从dev"升级到测试"到生产".

解决方案

无处不在的脚本最初由 .

I want to be able to tell what path my executing script was run from.
This will often not be $pwd.

I need to call other scripts that are in a folder structure relative to my script and while I could hard code the paths, that's both distasteful and a bit of a pain in the neck when trying to promote from "dev" to "test" to "production".

解决方案

The ubiquitous script originally posted by Jeffrey Snover of the PowerShell team (given in Skyler's answer) and the variations posted by Keith Cedirc, and EBGreen, all suffer from a serious drawback--whether the code reports what you expect depends on where you call it!

My code below overcomes this problem by simply referencing script scope instead of parent scope:

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

To illustrate the problem, I created a test vehicle that evalutes the target expression in four different ways. (The bracketed terms are the keys to the following result table.)

  1. inline code [inline]
  2. inline function, i.e. function in the main program [inline function]
  3. Dot-sourced function, i.e. the same function moved to a separate .ps1 file [dot source]
  4. Module function, i.e. the same function moved to a separate .psm1 file [module]

The last two columns show the result of using script scope (i.e. $script:) or with parent scope (with -scope 1). A result of "script" means that the invocation correctly reported the location of the script. The "module" result means the invocation reported the location of the module containing the function rather than the script that called the function; this indicates a drawback of both functions that you cannot put the function in a module.

Setting the module issue aside the remarkable observation from the table is that using the parent scope approach fails most of the time (in fact, twice as often as it succeeds).

Finally, here is the test vehicle:

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

Contents of ScriptDirFinder.ps1:

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

Contents of ScriptDirFinder.psm1:

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

I am not familiar with what was introduced in PowerShell 2, but it could very well be that script scope did not exist in PowerShell 1, at the time Jeffrey Snover published his example.

I was surprised when, though I found his code example proliferated far and wide on the web, it failed immediately when I tried it! But that was because I used it differently than Snover's example (I called it not at script-top but from inside another function (my "nested twice" example).)

2011.09.12 Update

You can read about this with other tips and tricks on modules in my just-published article on Simple-Talk.com: Further Down the Rabbit Hole: PowerShell Modules and Encapsulation.

这篇关于如何找到正在执行的脚本的源路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆