powershell if-else 不遵循任一分支

2024-01-08

我有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 仍设置为“初始值”的情况下完成此部分。

if-else 结构怎么能不遵循任何一条路径呢?当 if 函数给出错误而不是 true 或 false 时,powershell 中的 if-else 结构是否不执行任何操作?

$PSVersionTable.psversion 是 3.0

编辑:当我自己运行它时,无论是完全运行还是逐步运行,我都不会出现任何错误或此问题。但有时计划的作业将运行,并且 $DelTmpStatus 仍将是“初始值”我想当\\server\share\由于服务器夜间处于低功耗模式,响应时间过长且测试路径功能超时,路径不可用。虽然我不能确定这是否是原因。

编辑:测试结果

  • 使用不存在的服务器$target_dir让它遵循 else 路径并设置$DelTmpStatus to "NA"
  • 使用无效路径,例如$target_dir = "C:\..\..\invalid\"导致测试路径向 stderr 写入错误并返回 true (不理想,但无论如何),使程序向下尝试删除文件(再次出现错误),然后设置$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

The Fix

为了解决这个问题,需要从预先测试的 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)

不幸的是,这仍然让我想知道发生了什么......? “测试路径”如何在某些日子是有效的 cmdlet,而在其他日子却不是,并且在同一台计算机上从同一个计划作业运行完全相同的脚本。作为额外的奖励,在那些日子“测试路径”不是有效的 cmdlet https://stackoverflow.com/questions/22188829/powershell-test-path-is-not-recognized-as-a-cmdlet,当我稍后在同一脚本中再次使用它时,它每次都运行良好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

powershell if-else 不遵循任一分支 的相关文章

随机推荐