He estado buscando una forma de terminar un script de PowerShell (PS1) cuando se produce un error irrecuperable dentro de una función. Por ejemplo:
function foo() {
# Do stuff that causes an error
$host.Exit()
}
Por supuesto que no existe tal cosa $host.Exit()
. Lo hay $host.SetShouldExit()
, pero en realidad esto cierra la ventana de la consola, que no es lo que quiero. Lo que necesito es algo equivalente a Python sys.exit()
que simplemente detendrá la ejecución del script actual sin más adiós.
Editar: Sí, es solo exit
. Duh
powershell
kprobst
fuente
fuente
Respuestas:
Deberías usar la
exit
palabra clave .fuente
Me doy cuenta de que esta es una publicación antigua, pero me encuentro volviendo mucho a este hilo, ya que es uno de los principales resultados de búsqueda al buscar este tema. Sin embargo, siempre me dejo más confundido que cuando vine debido a la información conflictiva. En última instancia, siempre tengo que realizar mis propias pruebas para resolverlo. Así que esta vez publicaré mis hallazgos.
TL; DR La mayoría de las personas querrán usar
Exit
para terminar un script en ejecución. Sin embargo, si su script simplemente declara funciones para usarlas posteriormente en un shell, entonces querrá usarlasReturn
en las definiciones de dichas funciones.Salida vs retorno vs descanso
Salir: Esto "saldrá" del contexto actual. Si llama a este comando desde un script, saldrá del script. Si llama a este comando desde el shell, saldrá del shell.
Si una función llama al comando Salir, saldrá del contexto en el que se esté ejecutando. Entonces, si esa función solo se llama desde un script en ejecución, saldrá de ese script. Sin embargo, si su script simplemente declara la función para que pueda usarse desde el shell actual y ejecuta esa función desde el shell, saldrá del shell porque el shell es el contexto en el que
Exit
se ejecuta la función que contiene el comando.Nota: De forma predeterminada, si hace clic con el botón derecho en un script para ejecutarlo en PowerShell, una vez que el script se haya ejecutado, PowerShell se cerrará automáticamente. Esto no tiene nada que ver con el
Exit
comando o cualquier otra cosa en su secuencia de comandos. Es solo un comportamiento predeterminado de PowerShell para los scripts que se ejecutan utilizando este método específico de ejecutar un script. Lo mismo es cierto para los archivos por lotes y la ventana de línea de comandos.Regresar: Esto volverá al punto de llamada anterior. Si llama a este comando desde un script (fuera de las funciones), volverá al shell. Si llama a este comando desde el shell, volverá al shell (que es el punto de llamada anterior para un solo comando ejecutado desde el shell). Si llama a este comando desde una función, volverá a donde se llamó la función.
La ejecución de cualquier comando después del punto de llamada al que se devuelve continuará desde ese punto. Si se llama a un script desde el shell y contiene el
Return
comando fuera de cualquier función, cuando regrese al shell no hay más comandos para ejecutar, por lo que unReturn
uso de esta manera es esencialmente el mismo queExit
.Descanso: Esto saldrá de los bucles y cambiará los casos. Si llama a este comando mientras no está en un bucle o caso de cambio, saldrá del guión. Si llama
Break
dentro de un bucle que está anidado dentro de un bucle, solo saldrá del bucle en el que se llamó.También hay una característica interesante de
Break
dónde puede prefijar un bucle con una etiqueta y luego puede salir de ese bucle etiquetado incluso si elBreak
comando se llama dentro de varios grupos anidados dentro de ese bucle etiquetado.fuente
Exit
puede tomar un código de retorno como parámetro (el valor predeterminado es 0), por ejemploExit 3
.Get-Command Exit
yGet-Alias Exit
sin resultados. Luego miré para ver si era una palabra clave y no encontré documentación oficial al respecto. Mirándolo ahora, sin embargo, no sé cómo llegué a esa conclusión. Claramente es una palabra clave ( technet.microsoft.com/en-us/library/hh847744.aspx ). Quizás porque Exit es una de las únicas palabras clave que no tiene su propio tema about_ help y, por lo tanto, la lista de temas en la barra lateral izquierda no lo incluyó.Exit
también saldrá de PowerShell. Si desea "romper" solo la función o script actual, useBreak
:)fuente
break
cuando quiera simplemente salir de la función actual ... ¡los scripts de llamada también pueden verse afectados!Write-Error es para errores que no terminan y throw es para errores que terminan
fuente
powershell -command "& module-function ..."
. Necesitaba convertir esas funciones para lanzar un try-catch de envoltura y salir de esa captura de envoltura para realmente generar un código de salida de error.$PSCmdlet.ThrowTerminatingError()
de aquellos casos en los que throw simplemente no puede hacer el trabajo (problema conocido sin errores de terminaciónthrow
)Termina este proceso y le da al sistema operativo subyacente el código de salida especificado.
https://msdn.microsoft.com/en-us/library/system.environment.exit%28v=vs.110%29.aspx
[Environment]::Exit(1)
Esto le permitirá salir con un código de salida específico, que puede obtener de la persona que llama.
fuente
Exit 1
.[Environment]::Exit(1)
tiene el efecto secundario de salir de mi ventana de PowerShell cuando lo invoco en un script, dondeexit
parece que usarlo no lo hace.Creo que estás buscando en
Return
lugar deBreak
. La ruptura generalmente se usa para bucles y solo se rompe desde el bloque de código más interno. Use Volver para salir de una función o script.fuente
Return
simplemente regresará de la función, no del script. (Return
en el nivel superior de un guión terminará el guión, pero esa no era la pregunta).Lanzar una excepción será bueno, especialmente si desea aclarar la razón del error:
Esto generará un error de terminación.
fuente
Puede ser mejor usar "trap". Una captura de PowerShell especifica un bloque de código para ejecutarse cuando se produce una terminación o un error. Tipo
para aprender más sobre la declaración de trampa.
fuente
Casualmente descubrí que (por ejemplo , simplemente , donde la etiqueta no existe ) parece salir del guión completo (incluso desde una función) y mantiene vivo al host. De esta manera, podría crear una función que rompa el script desde cualquier lugar (por ejemplo, un bucle recursivo) sin conocer el alcance actual (y crear etiquetas):
Break <UnknownLabel>
Break Script
Script
fuente
Usé esto para volver a ejecutar un programa. No sé si ayudaría, pero es una declaración simple si solo requiere dos entradas diferentes. Funcionó en PowerShell para mí.
No sé si esto ayuda, pero creo que sería similar a la finalización de un programa después de haberlo ejecutado. Sin embargo, en este caso, cada entrada definida requiere una salida listada y categorizada. También puede hacer que la salida llame una nueva línea de solicitud y finalice el programa de esa manera.
fuente