powershell if-statement boolean-logic

powershell if-else no sigue ninguna rama



if-statement boolean-logic (1)

Parece que si el comando dentro del área de condición no puede ejecutarse y no devuelve un valor, no se ejecuta todo el bloque if-else y el error continuar continúa por debajo del bloque if-else.

Cómo simular el problema

Si bien esto no es exactamente lo que está sucediendo en mi código real, produce el mismo problema del bloque if-else que no se está ejecutando. Incluso lo hace todo el tiempo.

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"

tiene la salida

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

La solución

Para solucionar el problema, el código que puede tener un error debe eliminarse de la condición if () probada de antemano, y la lógica debe agregarse al enunciado if para tratar una falla potencial. Para arreglar el código actual y no sufrir este problema, ahora he cambiado el código a

$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" }

El astuto se dará cuenta de que podría simplemente reemplazar todo eso con solo las líneas

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

ya que trato de eliminar el archivo incluso si tiene un error al encontrar el archivo. La única diferencia será que el código más corto tendrá errores más a menudo pero aún realizará la misma función.

Sin embargo, tener el código más largo con más control de errores arroja un poco más de luz sobre la situación ya que $ tmpStatus ha llegado con el valor

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)

Desafortunadamente, esto todavía me deja pensando qué está pasando ... ¿Cómo puede ser que ''Test-Path'' sea un cmdlet válido algunos días pero no otros, con exactamente el mismo script ejecutándose en la misma computadora desde el mismo trabajo programado. Como bonificación adicional, en los días en que ''Test-Path'' no es un cmdlet válido , cuando lo uso más adelante en el mismo script, funciona bien todo el tiempo.

Tengo el código de 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" }

y a veces lo hace a través de esta sección con $ DelTmpStatus todavía establecido en "valor de inicio".

¿Cómo puede la estructura if-else no seguir ninguna de las rutas? ¿La estructura if-else en powershell no hace nada cuando la función if recibe un error en lugar de verdadero o falso?

$ PSVersionTable.psversion is 3.0

Editar: nunca tengo ningún error o este problema cuando lo ejecuto yo mismo, ya sea completamente o paso a paso. Pero a veces el trabajo programado se ejecutará y $ DelTmpStatus seguirá siendo "valor de inicio". Imagino que sucede cuando el //server/share/ recurso //server/share/ ruta no está disponible debido a que el servidor en modo de bajo consumo toma demasiado tiempo para responder y el camino de prueba la función se agota. Aunque no puedo estar seguro de si esa es la causa o no.

Editar: los resultados de hacer las pruebas

  • el uso de un servidor no existente para $target_dir hace que siga la ruta else y establece $DelTmpStatus en "NA"
  • usar una ruta inválida como $target_dir = "C:/../../invalid/" da como resultado test-path escribiendo un error en stderr y devolviendo true (no ideal pero lo que sea), haciendo que el programa fluya hacia abajo en el intento de eliminar el archivo (de nuevo hay un error) luego establece $DelTmpStatus a "Presentar y eliminar el estado Falso". Esto no es particularmente útil, pero al menos se ejecuta el código en la instrucción if-else.