问题
我正在使用Jenkins远程部署PowerShell脚本。因此,我试图弄清楚使用$MyInvocation.MyCommand.Path
获取当前脚本根目录是否会出现问题。
详情
一位同事告诉我,使用$PSScriptRoot
对于远程功能来说是一个坏主意,因为我可能偶尔会发现它在运行时由于某种原因没有返回预期的值,即使它以前工作过。但是,无法解释为什么会这样。
在我的研究中,我没有发现任何可以进一步解释这一点的东西,或者避免这种问题的最佳实践方法是什么。然而,$PSScriptRoot
只能在PowerShell v3或更高版本中使用。通过你们中的一些人的帮助,我还了解到$MyInvocation
有不同的情况,允许它根据范围和模块进行更改。但我仍然没有发现这是否或为什么会是PowerShell Remoting的问题。
- 实施例001*
所以我在Jenkins中有一个PowerShell脚本,它使用$PSScriptRoot
作为查找我希望通过相对路径调用的脚本的方法。我是否能够依赖于此始终为所述脚本提供相同/预期的路径?
- 实施例002*
使用由Jenkins启动的PowerShell脚本调用的PowerShell脚本,我是否能够期望$PSScriptRoot
能够为我提供该脚本实际所在的路径,或者它会给予我一个基于Jenkins的路径?
就我个人而言,我希望$PSScriptRoot
能为我提供正在运行的脚本的实际物理位置,而不是根据调用它的初始脚本而变化的相对路径。
因为有了这种理解将帮助保存我很多时间和头痛,我希望像你这样的程序员可以帮助启发我,如果这是真的,为什么会发生这样的问题。
问题
我想知道使用$PSScriptRoot
是否会在PowerShell Remoting中导致问题,从而使使用$MyInvocation
成为更可行的选择?
3条答案
按热度按时间vsdwdz231#
字符串
$PSScriptRoot
是一个自动变量,它只保存当前脚本目录的字符串对象。型
$MyInvocation
是一个自动变量,有着非常不同的类型,为每个作用域生成。它的成员和实用程序因作用域而异。kgsdhlau2#
记住,这两个变量都指向正在执行的 file。如果没有file,它们就是空的。
在远程处理中,就像使用
Invoke-Command -ScriptBlock { }
时一样,没有文件。如果您在远程处理会话中调用模块中的函数,并且该函数使用
$PSScriptRoot
或$MyInvocaton...
,则它可能会返回它所在的任何文件。Jenkins创建了一个临时文件,并从该文件中运行代码,因此该文件将被返回。
qybjjes13#
虽然
(Split-Path -Parent ($MyInvocation.MyCommand.Path))
是返回路径的两个命令选项中较长的一个,正如@'Maximilian Burszley'指出的那样,$PSScriptRoot
是一个简单的字符串,如果你从一个模块或子脚本中调用,而不是与主脚本位于同一路径中,那么$PSScriptRoot
可能会返回一个错误的路径。更大的陷阱(IMO)是从子作用域调用任何一个命令,就像上面指出的使用
Invoke-Command -ScriptBlock { }
时一样。