问题
I have a script with several files I'd like to copy and I do it more or less like so.
Copy-Item xxx1 yyy1 -Force
Copy-Item xxx2 yyy2 -Force
Copy-Item xxx3 yyy3 -Force
Copy-Item xxx4 yyy4 -Force
and so on.
Now I'd like this script to exit with 1 if any of the files was not copied.
Thanks in advance
回答1:
What you're asking for is similar to the set -e
option in bash
, which causes a script to exit instantly in the event that a command signals failure (except in conditionals)[1].
PowerShell has no such option[2], but you can emulate it:
# Set up a trap (handler for when terminating errors occur).
Trap {
# Print the error.
# IMPORTANT: -ErrorAction Continue must be used, because Write-Error
# itself would otherwise cause a terminating error too.
Write-Error $_ -ErrorAction Continue
exit 1
}
# Make non-terminating errors terminating.
$ErrorActionPreference = 'Stop'
# Based on $ErrorActionPreference = 'Stop', any error reported by
# Copy-Item will now cause a terminating error that triggers the Trap
# handler.
Copy-Item xxx1 yyy1 -Force
Copy-Item xxx2 yyy2 -Force
Copy-Item xxx3 yyy3 -Force
Copy-Item xxx4 yyy4 -Force
# Failure of an EXTERNAL PROGRAM must be handled EXPLICITLY,
# because `$ErrorActionPreference = 'Stop'` does NOT apply.
foo.exe -bar
if ($LASTEXITCODE -ne 0) { Throw "foo failed." } # Trigger the trap.
# Signal success.
exit 0
Note:
PowerShell-internally, exit codes are not used in error handling; they typically only come into play when invoking external programs from PowerShell, or when PowerShell / a PowerShell script needs to signal success vs. failure for the outside world (when called from another shell, such as
cmd
on Windows, orbash
on Unix-like platforms).PowerShell's automatic
$LASTEXITCODE
variable reflects the exit code of the most recently executed external program / PowerShell script that calledexit <n>
.Calls to external (console/terminal) programs that signal failure via a nonzero exit code do not trigger the
trap
block, hence the explicitthrow
statement in the snippet above.- Unless you set the exit code explicitly, it is the exit code of whatever external program happened to execute last that determines the script's overall exit code.
[1] Note that this option has its critics, because the exact rules around when a failure is tolerated and when it causes a script to abort are hard to remember - see http://mywiki.wooledge.org/BashFAQ/105
[2] Potentially adding support for it is being discussed in this RFC proposal.
回答2:
You can do something like this, and it will exit with the number of powershell command errors.
$errorcount = $error.count
Copy-Item xxx1 yyy1 -Force
Copy-Item xxx2 yyy2 -Force
Copy-Item xxx3 yyy3 -Force
Copy-Item xxx4 yyy4 -Force
exit $error.count - $errorcount
来源:https://stackoverflow.com/questions/53248823/powershell-copy-item-exit-code-1