当我从任何文件夹(例如C:\Scripts
)启动PowerShell脚本时,
脚本中的“当前” PowerShell文件夹
始终是用户配置文件文件夹(例如c:\users\Joe
)
(使用仅包含Get-Location
的脚本进行测试)
但是应该是启动脚本的文件夹...
我该如何解决?
答案 0 :(得分:2)
当PowerShell 直接直接调用*.ps1
脚本时,该脚本在与调用方相同的运行空间中运行进程内 ,因此脚本默认情况下将相同当前位置(工作目录)视为呼叫者。
顺便说一句:相反,如果脚本更改当前位置,则在脚本退出后,调用方也会看到该信息(详细信息,请参见下文)。
如果您没有看到此行为,则表示一些幕后代码正在更改当前位置。 < / p>
我可以实际看到此情况的唯一方法是在以下情况下:
如果(a)您的$PROFILE
文件包含Set-Location
/ Push-Location
命令,该命令明确切换到您的主文件夹或(b)(就像您的情况一样,我们现在知道)自动加载模块中是否存在代码损坏,该代码在(自动)import [1] 和上执行此操作:
您通过其CLI(对于 Windows PowerShell 是powershell.exe
,对于PowerShell Core 是pwsh
)来调用PowerShell < em>没有-NoProfile
开关;例如powershell -File someScript.ps1
在类似Unix的平台上,您的脚本已实现并被称为带有shebang行的不扩展的可执行shell脚本(不包含-NoProfile
-有关详细信息,请参见下文)。 / p>
如果通过以下命令/功能之一运行脚本:
通过Start-Job
(在子进程中)或Start-ThreadJob
(在新的运行空间中),至少当前是这样(PowerShell Core 7.0.0-preview.4)
在新的运行空间中通过PowerShell SDK。
除此之外,我只能看到基于偶然事件的代码会产生您的症状,例如以下内容-无意义-重新定义了交互式提示字符串定义函数prompt
,使它在每个命令之后悄悄地切换到$HOME
目录:
# !! Obviously, do NOT do this.
function prompt {
# Print the usual prompt string.
"PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "
# Quietly return to $HOME
Set-Location $HOME
}
其余的答案讨论了可能感兴趣的相关场景。
在PowerShell v3 +中,自动变量$PSScriptRoot
包含执行脚本所在目录的完整路径。
如果您需要脚本以其自己的目录作为工作目录执行(当前位置),请使用以下方法:
# Switch to this script's directory.
Push-Location -LiteralPath $PSScriptRoot
try {
# Your script's body here.
# ...
$PWD # output the current location
}
finally {
# Restore the previous location.
Pop-Location
}
注意:
显式还原先前位置(目录)的原因是 PowerShell在运行中的脚本(.ps1
文件)( ),因此如果脚本使用 Set-Location
或Push-Location
更改当前位置,全局生效 session ;也就是说,即使脚本退出后,新位置仍会停留。
在类Unix平台(Linux,macOS)上,使用PowerShell Core ,您现在可以选择创建(无扩展名)可执行Shell <带有this GitHub issue 的strong>脚本;这样的脚本在子进程 中运行,因此 不需要还原以前的位置(目录)
$PSScriptRoot
)的访问,包括<{>} 。 shebang line。 [1]任何模块都不应在导入时更改会话全局状态(除了导入其命令),但是从技术上讲,它是可能的,即如果您放置诸如{ {1}}位于脚本模块的Set-Location
文件的顶级范围中,或者位于通过*.psm1
module-manifest条目在调用者范围内运行的脚本中。甚至二进制cmdlet也可以在导入时通过ScriptsToProcess
接口执行代码-请参见this GitHub issue。