假设我有一个简单的范围,通过Push-Location和Pop-Location以书结尾:
Function MyFunction($Location)
{
Push-Location $Location
# do other stuff here
Pop-Location
}
有没有办法在范围的开头设置它,这样我就不必记得将Pop-Location放在最后?像这样:
Function MyFunction($Location)
{
Setup-BothPushAndPopHere $Location
# do other stuff here
# at the end of the scope, Pop-Location is automatically called
}
答案 0 :(得分:6)
简短回答:不。
我对Push-Location
和Pop-Location
的看法是,您通常应该避免使用它们,并调整脚本以使用命令中的路径名;换句话说,而不是:
Push-Location $Location
Get-ChildItem
Pop-Location
只是做:
Get-ChildItem $Location
(简化示例)
如果您必须使用该模式,请考虑try
/ finally
:
Push-Location $Location
try {
# ...
} finally {
Pop-Location
}
因为这有助于意外异常或用户中断程序执行。
当代码超出我的控制范围时,我通常使用try
/ finally
模式;最常见的是在加载SQLPS
模块时,因为它将当前位置更改为SQL服务器提供程序,根据我的经验,这会导致使用当前位置的所有内容变慢。
正如Eris指出的那样,它在处理本机应用程序时也很有用。如果使用空格绕过带有空格的路径名称的引号很痛苦,或者应用程序无论如何都无法正确处理它,那么尤其如此。
答案 1 :(得分:1)
根据您在#do other stuff here
代码中尝试执行的操作,您可以尝试将这些命令作为子进程中的脚本块执行。骨架代码示例:
$ScriptBlock = {
Push-Location $Location
#commands
}
$Job = Start-Job -ScriptBlock $ScriptBlock # Add other arguments if needed
# Check the status of the task:
Get-Job $Job
# Wait for the job state to be 'Completed' (do-while, maybe?)
# If your ScriptBlock writes any output, collect in a variable:
$Output = Receive-Job $Job
# Clean up:
Remove-Job $Job
这种方法的关键在于你产生了一份工作来完成工作(在后台)你不必担心Pop-Location
因为你只是让那个孩子的范围退出而你继续做任何事情你需要在主脚本中完成。
StackExchange上还有其他帖子详细介绍了powershell-jobs。
答案 2 :(得分:0)
这是使用脚本块实现的一种很酷的方法
function withPath($action,$path) {
Push-Location $path
try
{
& $action
}
finally
{
Pop-Location
}
}
withPath {
Get-Location | Write-Host
withPath {
Get-Location | Write-Host
throw "oh no, an inner exception!"
} 'Program Files' #relative path
} 'C:\'