Maestro PowerShell Pause: Técnicas de Línea de Comando y Scripting

Hay muchas razones para pausar la ejecución de un script. Tal vez un script necesita esperar la entrada del usuario, disminuir la velocidad de ejecución o aguardar a que otro proceso concluya antes de seguir adelante. Como con la mayoría de las tareas en PowerShell, hay más de una forma de pausar un script. Dependiendo de lo que estés tratando de lograr, el método de pausa que elijas tendrá sus fortalezas y debilidades. Añadiendo otra complejidad a las opciones disponibles está la nueva capacidad multiplataforma de PowerShell. Dado que PowerShell se utiliza a menudo como una forma de “pegar” diferentes tecnologías, al igual que en Windows, la línea de comandos de Linux tiene sus opciones para pausar la ejecución que también se pueden incorporar a PowerShell.

Métodos de Pausa en PowerShell

¿Cuáles son las diferentes formas de pausar la ejecución de un script? En este artículo, vamos a desglosar la capacidad de pausa en comandos nativos y no nativos. Por “nativos”, nos referimos a aquellos comandos que son funciones o métodos integrados en PowerShell o .NET. Los métodos no nativos se definen como programas específicos de Windows y Linux que podrían usarse junto con PowerShell.

Métodos Nativos

  • Start-Sleep
  • [System.Threading.Thread]::Sleep()
  • Read-Host
  • [Console]::ReadKey()
  • $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Métodos no Nativos

Windows

  • pause
  • timeout

Linux

  • sleep
  • leer -p

Como puedes ver, hay varias opciones diferentes, cada una con sus ventajas y desventajas. Cuál uses influirá en cómo se pausa la ejecución y qué otros efectos puede tener esa pausa.

Métodos Nativos

Para empezar, vamos a describir los métodos nativos ya que son los más utilizados en scripts.

Start-Sleep

El comando de pausa más comúnmente utilizado es, con mucho, Start-Sleep. Este comando toma dos simples entradas, que son -Seconds y -Milliseconds. Los segundos pueden ser un valor numérico System.Double mientras que los milisegundos solo aceptan valores System.Int32. Al combinar los dos, se puede lograr un control preciso sobre la duración de la pausa. Start-Sleep también tiene un alias de sleep.

Start-Sleep -Seconds 2 -Milliseconds 300

Antes de PowerShell 6.2.0, no se podía escribir un valor de segundos fraccionarios como, 2.3 que es la misma duración de tiempo por la que estamos pausando en el código anterior. Con 6.2.0, los valores fraccionarios ahora son compatibles, así que en lugar de escribir los segundos y milisegundos de forma independiente, ahora puedes especificar: -Seconds 2.3.

Es importante tener en cuenta que puedes salir de una función de Start-Sleep usando Ctrl-C. ¡Esto no es cierto para todos los métodos!

Dormir Hilo

A less commonly used method of pausing execution is the [System.Threading.Thread]::Sleep() .NET method. By passing in a System.Int32 or a TimeSpan value, this allows pausing of the current thread for a set amount of time. For example, to pause by that same amount of time, 2.3 seconds, as in our Start-Sleep example, we can write:

[System.Threading.Thread]::Sleep(2300)

Para utilizar un intervalo de tiempo con el método Thread Sleep, puedes hacer lo siguiente:

[System.Threading.Thread]::Sleep([TimeSpan]::New(0, 0, 0, 2, 300))

Para pausar indefinidamente un hilo, puedes utilizar el [System.Threading.Timeout]::InfiniteTimeSpan, pero ten en cuenta que esto puede bloquear tu proceso.

A diferencia de Start-Sleep, el método Thread Sleep no te permite salir de la rutina de suspensión usando Ctrl-C. Dependiendo de tu aplicación, esto puede ser preferible.

También es importante saber que el Thread Sleep no garantiza un tiempo exacto. Todo Thread Sleep tiene la garantía de que esperará al menos esa cantidad de segundos. Dado que los conteos de Thread Sleep coinciden con los ticks del reloj, otros programas pueden interrumpir esta función de pausa y obligar a esperar más tiempo.

Aunque el Thread Sleep tiene sus usos, es mejor usar uno de los otros métodos integrados debido a estos problemas.

Leer-Host

Los métodos anteriores describen formas de pausar la ejecución, pero solo por una cantidad establecida de tiempo. Otra forma de pausar la ejecución es solicitando la entrada del usuario. Con este método, se debe realizar una acción manual, pero puede ser muy útil requerir una confirmación para continuar y posiblemente incluir una entrada adicional.

El Read-Host es una de las formas más comunes de solicitar la entrada del usuario. Al solicitar la entrada del usuario, la entrada resultante se puede guardar para su uso posterior en el código o para pausar la ejecución según sea necesario.

Read-Host -Prompt "Press any key to continue"

Una vez que se ha ingresado texto, es necesario presionar la tecla enter o retorno para continuar con la ejecución. Al hacerlo, y sin guardar la entrada en una variable, esto mostrará el mismo texto ingresado en la consola.

Press Enter to Move Execution Along

Si desea guardar el texto resultante ingresado en una variable para su uso posterior, simplemente asígnele la entrada de Read-Host a una variable.

$Input = Read-Host -Prompt "Press any key to continue"

A veces puede que desee leer la entrada como una cadena segura. Afortunadamente, Read-Host hace que esto sea trivialmente fácil.

$SecureInput = Read-Host -Prompt "Enter your password" -AsSecureString

Ctrl-C le permitirá salir del prompt de Read-Host.

Método Console ReadKey

Usando el método [Console]::ReadKey(), puede leer fácilmente comandos de teclas, junto con modificadores, mientras pausa la ejecución del programa. De forma predeterminada, los comandos de teclas enviados se reflejan en la pantalla como un objeto System.ConsoleKeyInfo. Esto incluye los valores de Key, KeyChar y Modifiers, que pueden ser muy útiles al verificar ciertas combinaciones de teclas.

[Console]::ReadKey()
Console ReadKey Command

A menudo puede que desee verificar una entrada de tecla específica antes de continuar de manera continua. Esto se puede hacer fácilmente utilizando un bucle Do-While como se muestra a continuación.

Do {
	$Key = [Console]::ReadKey($True)
	Write-Host $Key.Key
} While ( $Key.Key -NE [ConsoleKey]::Escape )
Do-While Loop Key

Por favor, ten en cuenta que dado que estamos buscando una combinación de teclas específica, Ctrl-C no interrumpirá la entrada aquí.

Host RawUI Método ReadKey

Finalmente, tenemos el método $host.UI.RawUI.ReadKey(). Esto es similar al método Console ReadKey, pero este método permite pasar opciones adicionales al método ReadKey para controlar el comportamiento y la salida aún más.

$host.UI.RawUI.ReadKey()
RawUI.ReadKey

Hay varios ReadKeyOptions que se pueden pasar, lo que puede hacer que el método RawUI ReadKey sea más útil.

  • AllowCtrlC
  • IncludeKeyDown
  • IncludeKeyUp
  • NoEcho

Esto se puede usar de la siguiente manera, incluyendo eventos de tecla pulsada y sin eco del texto.

$host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')

Este método permitirá el uso de Ctrl-C para salir del comando, excepto si se utiliza la opción AllowCtrlC.

Métodos No Nativos

En esta sección, exploramos algunos métodos no nativos para pausar la ejecución de secuencias de comandos. Estos métodos están destinados a utilizar utilidades específicas de la consola no nativa de PowerShell que se pueden integrar en secuencias de comandos de PowerShell según tus necesidades.

Windows

Pausa

El comando de pausa es muy simple y mostrará `Presiona cualquier tecla para continuar. . . y permanecerá así hasta que se presione una tecla para reanudar la ejecución.

cmd /c 'pause'
Pause Command

Puedes preguntarte cómo usar esto en un script, pero al igual que cualquier otro comando, inserta el comando `cmd /c 'pause'` dentro de tu script para utilizar la funcionalidad nativa.

Cmd/C Pause Command

Timeout

Normalmente utilizado en archivos por lotes de Windows, el comando timeout permite pausar durante un número especificado de segundos y, opcionalmente, ignorar cualquier comando de tecla. Un toque de tecla del usuario normalmente reanudará la ejecución incluso si no ha transcurrido el período de tiempo de espera. Se usa muy simplemente pasando el número de segundos.

# Pausar durante 2 segundos
timeout /t 2

# Pausar durante 5 segundos pero prohibir interrupciones por teclas
timeout /t 5 /nobreak

# Pausar indefinidamente hasta que se presione una tecla
timeout /t -1
Timeout Command

Al igual que con el comando pause, inserta el comando timeout dentro del script y en el ejemplo a continuación, presionamos la tecla Enter para continuar.

Timeout Command Execution

Linux

Sleep

Al igual que el comando pause en Windows, el comando sleep en Linux permite establecer un valor arbitrario para el tiempo de espera. A diferencia del comando de pausa, el comando sleep tiene algunas opciones más que permiten flexibilidad en el tiempo de espera.

sleep 2.3s
Sleep Command

El comando sleep también opcionalmente tiene sufijos que permiten definir períodos de tiempo más largos. Ejemplos:

  • sleep 1m – Dormir durante un minuto
  • sleep 2h – Dormir durante dos horas
  • sleep 1d – Dormir durante un día

Leer -P

Finalmente, otra forma en que Linux puede pausar es usando la aplicación read para pausar hasta que se presione la tecla Enter para continuar la ejecución. Hay un parámetro opcional de tiempo de espera que continuará la ejecución si la tecla Enter no se presiona en el tiempo especificado.

read -p 'Press enter to continue' -t 5
Read Application to Pause

Conclusión

Como puedes ver, hay muchas formas de pausar la ejecución dentro de un script o en la línea de comandos. Dependiendo de tus necesidades, podría ser tan simple como un comando Start-Sleep o un proceso más complejo impulsado por la entrada. Combinado con los comandos nativos, la pausa de PowerShell permite flexibilidad en casi cualquier entorno y utilidad máxima del script.

Source:
https://adamtheautomator.com/powershell-pause/