Powershell位运算符比较用于Robocopy退出代码

5

我无法理解这个位运算转换问题。

Robocopy退出代码与正常的0(成功),1(失败)模式不符,因此我想使用下面的powershell脚本包装我的robocopy调用,以使我的TeamCity构建配置在robocopy终止时失败或恰当进行。

第一个部分是使用网上的技巧解决的: ($LastExitCode -band 24) 正确地将退出代码8到16作为失败(1),所有其他代码作为成功(0)。

现在我想回显与退出代码相对应的消息。如何将整数退出代码(0-16)转换并四舍五入/向下取整为其十六进制等效项(0x00-0x10)?

param(
    [string] $source,
    [string] $target,
    [string[]] $action = @("/MIR"),
    [string[]] $options = @("/R:2", "/W:1", "/FFT", "/Z", "/XA:H")
)
$cmd_args = @($source, $target, $action, $options)
& robocopy.exe @cmd_args
$returnCodeMessage = @{
    0x00 = "[INFO]: No errors occurred, and no copying was done. The source and destination directory trees are completely synchronized."
    0x01 = "[INFO]: One or more files were copied successfully (that is, new files have arrived)."
    0x02 = "[INFO]: Some Extra files or directories were detected. Examine the output log for details."
    0x04 = "[WARN]: Some Mismatched files or directories were detected. Examine the output log. Some housekeeping may be needed."
    0x08 = "[ERROR]: Some files or directories could not be copied (copy errors occurred and the retry limit was exceeded). Check these errors further."
    0x10 = "[ERROR]: Usage error or an error due to insufficient access privileges on the source or destination directories."
}
Write-Host $returnCodeMessage[($LastExitCode <what goes here?>)]
exit ($LastExitCode -band 24)
2个回答

2
在您的情况下,您不需要进行转换。 您不需要转换,因为Hashtable键在预编译阶段会被转换为[int]类型。 如果您查找$returnCodeMessage.Keys,您将看到十进制数字,而不是十六进制数字。
要显示所有消息,请使用
$exitcode = $LastExitCode    
Write-Host $( @( $returnCodeMessage.Keys | Where-Object { $_ -band $exitcode } | ForEach-Object {return $returnCodeMessage[$_]}   ) -join "`r`n")

如果您想显示十六进制编码的 $LastExitCode,请执行以下操作:

$exitcode = $LastExitCode
Write-Host $('0x' + [System.Convert]::ToString([int]$exitcode,[int]16) )
return $exitcode

String System.Convert.ToString(Int32, Int32)


1

正如filimonic提到的那样, 0x1016只是写同一基础数值的不同方式(即0x10 -eq 16计算结果为true),因此不需要进行转换。

为了显示组合返回代码中的每个消息,您可以依次测试每个单独的标志值:

if( $returnCodeMessage.ContainsKey( $LastExitCode ) ) {
    $returnCodeMessage[$LastExitCode]
}
else {
    for( $flag = 1; $flag -le 0x10; $flag *= 2 ) {
        if( $LastExitCode -band $flag ) {
            $returnCodeMessage[$flag]
        }
    }
}

对于像0x00(无更改)或0x04(不匹配)这样只包含一条消息的返回代码,我们直接查找它。否则,对于像0x09(部分复制,部分未复制)或0x13(部分复制,部分额外,访问被拒绝)这样的组合代码,我们检查每种可能性并输出与之匹配的结果。
此外,由于“任何大于8的值都表示在复制操作期间至少有一个失败”,因此您可以使用$LastExitCode -ge 8而不是$LastExitCode -band 24来测试错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接