如果抛出未捕获的异常,如何在PowerShell脚本中还原目录更改?

时间:2018-04-23 08:42:26

标签: powershell

在bash中,如果我想更改单个命令do_thing的当前目录,我会生成一个新的子shell,在其中更改目录,运行

(cd folderName; do_thing)

this question的正文表明在PowerShell中执行此操作的方法是使用Push-Location来存储位置,并在命令运行完成后使用Pop-Location。这有效,但并不理想:我必须记住在脚本的每个返回点写入Pop-Location(例如,在每个异常之前,如果在按下位置时发生),未捕获的异常将离开当前目录原样。

有没有办法让当前目录重置为脚本开头的内容,即使抛出了未捕获的异常?

2 个答案:

答案 0 :(得分:6)

try...catch...finally是您正在寻找的构造!

这将允许您处理错误并执行最终操作;主试块是否成功。

这是一个基本的例子:

try {
    $x = 1/0
}
catch {
    Write-Warning "An error occurred"
}
finally {
    Write-Output "This always runs"
}

更适合您的情况:

Write-Output "BEFORE: $(Get-Location)"

Push-Location -Path "C:\temp\csv"

try {
    Write-Output "DURING TRY: $(Get-Location)"
    $x = 1/0
}
catch {
    Write-Warning "An error occurred"
}
finally {
    Pop-Location
}

Write-Output "AFTER: $(Get-Location)"

结果:

  

BEFORE:C:\ temp

     

在尝试期间:C:\ temp \ csv

     

警告:发生错误

     

AFTER:C:\ temp

答案 1 :(得分:3)

Bash子shell作为子进程生成,因此它们不会修改其父级的环境,而PowerShell(子)表达式在同一PowerShell进程中运行,因此会修改该进程的环境。要在单独的流程中运行PowerShell语句,您需要Start-ProcessStart-Job之类的内容,例如

Start-Job -ScriptBlock {
    Set-Location folderName
    do_thing
} | Wait-Job | Receive-Job

Push-LocationPop-Location相当于bash中的pushdpopd