在bash中,如果我想更改单个命令do_thing
的当前目录,我会生成一个新的子shell,在其中更改目录,运行
(cd folderName; do_thing)
this question的正文表明在PowerShell中执行此操作的方法是使用Push-Location
来存储位置,并在命令运行完成后使用Pop-Location
。这有效,但并不理想:我必须记住在脚本的每个返回点写入Pop-Location
(例如,在每个异常之前,如果在按下位置时发生),未捕获的异常将离开当前目录原样。
有没有办法让当前目录重置为脚本开头的内容,即使抛出了未捕获的异常?
答案 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-Process
或Start-Job
之类的内容,例如
Start-Job -ScriptBlock {
Set-Location folderName
do_thing
} | Wait-Job | Receive-Job
Push-Location
和Pop-Location
相当于bash中的pushd
和popd
。