powershell判断 - powershell条件式



PowerShell的if-else不遵循任何分支 (1)

我有PowerShell代码

$target_dir = "\\server\share\"
$DelTmpStatus = "init value"
if ( Test-Path ( $target_dir + "receivals.tmp") )
{
    del ( $target_dir + "receivals.tmp")
    $DelTmpStatus = "Present and delete status $?"
} else {
    $DelTmpStatus = "NA"
}

有时它通过这个部分使$ DelTmpStatus仍然被设置为“init值”。

if-else结构怎么可能不遵循任一路径? 当if函数被赋予一个错误而不是true或false时,powershell中的if-else结构不会做任何事情吗?

$ PSVersionTable.psversion是3.0

编辑:我从来没有任何错误或这个问题,当我自己运行它,完全或一步一步。 但有时计划的作业将运行,$ DelTmpStatus仍然是“初始值”我想象当\\server\share\路径不可用,由于服务器处于低功耗模式一夜之间花费太长的时间来响应和测试路径功能超时。 虽然我不确定这是否是原因。

编辑:做测试的结果

  • $target_dir使用不存在的服务器使其跟随else路径并将$DelTmpStatus设置为“NA”
  • 使用像$target_dir = "C:\..\..\invalid\"这样的无效路径导致测试路径将错误写入stderr并返回true(不理想,但是不管),从而使程序向下流动该文件(再次出现错误),则将$DelTmpStatus设置$DelTmpStatus并删除状态False”。 这不是一个特别有用的事情,但是至少if-else语句中的代码被执行。

看起来,如果条件区域内的命令执行失败并且没有返回值,则整个if-else块不会被执行,继续错误选择继续在if-else块之下。

如何模拟问题

虽然这并不是真正的代码中发生的事情,但它确实会产生与执行if-else块相同的问题。 它甚至每次都这样做。

if ( Test-Path -invalid-switch )
{
    write-output "true path of if statement"
} else {
    write-output "false path of if statement"
}
write-output "finished if statement"

有输出

Test-Path : A parameter cannot be found that matches parameter name 'invalid-switch'.
At C:\scripts\test.ps1:1 char:16
+ if ( Test-Path -invalid-switch )
+                ~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Test-Path], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.TestPathCommand

finished if statement

修正

为了解决这个问题,可能有错误的代码需要从事先测试的if()条件中取出,并且将逻辑添加到if语句中以处理潜在的故障。 要修复实际的代码不受这个问题,我现在已经改变了代码

$err = $false
try { $tmpStatus = Test-Path ( $target_dir + "receivals.tmp") }
catch
{
    $tmpStatus = $error | foreach { $_.Exception }
    $err = $true
}
if ( $err -or $tmpStatus ) 
{
    del ( $target_dir + "receivals.tmp")
    $DelTmpStatus = $?
} else {
    $DelTmpStatus = "NA"
}

敏锐的人会意识到,我可以用线来代替所有这些

$tmpStatus = test-path ( $target_dir + "receivals.tmp")
del ( $target_dir + "receivals.tmp")
$DelTmpStatus = $?

因为我试图删除文件,即使它有一个错误找到文件。 唯一的区别是,较短的代码会有更多的错误,但仍然执行相同的功能。

然而,具有更多错误检查的更长的代码在$ tmpStatus已经通过值

System.Management.Automation.CommandNotFoundException: The term 'Test-Path' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
   at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
   at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

不幸的是,这仍然让我想知道发生了什么...? “Test-Path”如何在几天内成为有效的cmdlet,而不是其他人,使用完全相同的脚本从相同的计划作业在同一台计算机上运行。 作为一个额外的好处,在“测试路径”不是有效的cmdlet的日子,当我以后再次使用它在同一个脚本,它每次都工作得很好。





boolean-logic