掌握 PowerShell Pause:命令行和腳本技術

有很多原因可以暫停腳本的執行。也許腳本需要等待使用者輸入、減慢執行速度,或者在繼續前等待其他進程完成。就像在 PowerShell 中的大多數任務一樣,有多種方法可以暫停腳本。根據您想要達到的目標,您選擇的暫停方法將具有其優點和缺點。另一個可用選項的特殊之處在於 PowerShell 的新的跨平台能力。由於 PowerShell 經常被用作“粘合”不同技術的方式,就像在 Windows 中一樣,Linux 命令行也有其用於暫停執行的選項,也可以與 PowerShell 一起使用。

PowerShell 暫停的方法

有哪些不同的方法可以暫停腳本的執行?在本文中,我們將將暫停能力分為本機和非本機命令。本機命令是指那些 PowerShell 或 .NET 內置的函數或方法。非本機方法被定義為特定於 Windows 和 Linux 的程序,可以與 PowerShell 一起使用。

本機方法

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

非本機方法

Windows

  • pause
  • timeout

Linux

  • sleep
  • read -p

正如您所看到的,有许多不同的选项,每个选项都有其优点和缺点。您使用的选项将影响暂停执行的方式以及该暂停可能包含的其他效果。

本机方法

首先,我们将开始概述最常用于脚本的本机方法。

Start-Sleep

最常用的暂停命令无疑是Start-Sleep此命令接受两个简单的输入,即-Seconds-Milliseconds。秒可以是System.Double数值,而毫秒仅接受System.Int32值。通过结合这两个值,可以精确控制暂停的长度。Start-Sleep还有一个别名sleep

Start-Sleep -Seconds 2 -Milliseconds 300

在 PowerShell 6.2.0 之前,您无法编写类似于2.3这样的小数秒值,该值是我们在上面代码中暂停的时间长度。从 6.2.0 开始,小数值现在得到支持,因此您现在可以使用-Seconds 2.3来表示。不再需要单独写出秒和毫秒。

需要注意的是,您可以通过使用Ctrl-C退出Start-Sleep函数。这并不适用于所有方法!

線程休眠

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)

使用線程休眠方法時,可以使用TimeSpan構造進行以下操作:

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

要無限期暫停一個線程,可以使用[System.Threading.Timeout]::InfiniteTimeSpan,但請注意這可能會導致進程鎖死。

Start-Sleep不同,線程休眠方法不允許使用Ctrl-C中斷休眠過程。根據應用程序的不同,這可能是可取的。

還需要了解有關線程休眠的一點是,它並不保證準確的時間。所有線程休眠都保證至少等待指定的秒數。由於線程休眠與時鐘滴答相關,因此其他程序可能會中斷此暫停功能並強制等待更長的時間。

雖然線程休眠有其用途,但由於這些問題,最好使用其他內置方法之一。

Read-Host

上述方法描述了一些暫停執行的方式,但只能暫停一段時間。另一種暫停執行的方法是要求用戶輸入。使用這種方法,需要進行手動操作,但可以非常有用,以便要求確認繼續執行,並可能包括其他輸入。

Read-Host 是一種最常見的提示用戶輸入的方法之一。通過提示用戶輸入,可以將結果保存以供代碼進一步使用,或者根據需要暫停執行。

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

一旦輸入了文本,必須按下回車鍵或返回鍵來繼續執行。這樣做,並且不將輸入保存到變量中,將將輸入的相同文本輸出到控制台。

Press Enter to Move Execution Along

如果您想將輸入的結果文本保存到變量中以供以後使用,只需將 Read-Host 的輸入賦值給一個變量即可。

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

有時候您可能希望將輸入的文本作為安全字符串讀取。幸運的是,Read-Host 讓這變得非常簡單。

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

Ctrl-C 可以讓您中斷 Read-Host 的提示。

Console ReadKey 方法

使用 [Console]::ReadKey() 方法,您可以輕松地讀取鍵盤命令以及修飾符,同時暫停程序執行。默認情況下,發送的鍵盤命令將作為 System.ConsoleKeyInfo 對象回显到屏幕上。這包括 KeyKeyCharModifiers 的值,在檢查某些鍵組合時非常有用。

[Console]::ReadKey()
Console ReadKey Command

通常,在繼續之前,您可能希望檢查某個特定的鍵盤輸入。可以使用如下的 Do-While 循環輕松實現這一點。

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

請注意,由於我們正在尋找特定的鍵組合,Ctrl-C無法中斷此處的輸入。

主機 RawUI ReadKey 方法

最後,我們有 $host.UI.RawUI.ReadKey() 方法。這與 Console ReadKey 方法類似,但此方法允許將其他選項傳遞給 ReadKey 方法,以控制行為和進一步輸出。

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

可以傳入多個 ReadKeyOptions,這可能使 RawUI ReadKey 方法更有用。

  • AllowCtrlC
  • IncludeKeyDown
  • IncludeKeyUp
  • NoEcho

可以按照以下方式使用,該方式包含按下按鍵事件並且不顯示文字。

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

此方法將允許使用 Ctrl-C 中斷命令,除非使用 AllowCtrlC 選項。

非原生方法

在此部分中,我們將探討一些非原生的腳本執行暫停方法。這些方法用於根據您的需求,利用非 PowerShell 特定控制台工具將其整合到 PowerShell 腳本中。

Windows

Pause

暫停命令非常簡單,會顯示按任意鍵繼續 . . .,並保持該狀態,直到按下鍵盤上的任意鍵以恢復執行。

cmd /c 'pause'
Pause Command

你可能會問如何在腳本中使用這個命令,但就像使用其他命令一樣,在腳本中插入cmd /c 'pause'命令來使用原生功能。

Cmd/C Pause Command

Timeout

通常在Windows批處理文件中使用,timeout命令允許暫停指定的秒數,並可選擇忽略任何鍵盤輸入。即使超時期間尚未結束,用戶按鍵通常也會恢復執行。通過傳入秒數來使用它非常簡單。

# 暫停2秒
timeout /t 2

# 暫停5秒但禁止鍵盤中斷
timeout /t 5 /nobreak

# 無限暫停,直到按下鍵盤上的任意鍵
timeout /t -1
Timeout Command

pause命令一樣,將timeout命令插入腳本中,在下面的示例中,我們按下回車鍵以繼續執行。

Timeout Command Execution

Linux

Sleep

與Windows中的pause命令類似,Linux中的sleep命令允許設置任意的睡眠時間。與暫停命令不同,sleep命令還有一些其他選項,可以在睡眠時間上提供靈活性。

sleep 2.3s
Sleep Command

sleep 命令還可以選擇性地使用後綴,以定義更長的時間段。例如:

  • sleep 1m – 休眠一分鐘
  • sleep 2h – 休眠兩小時
  • sleep 1d – 休眠一天

使用 -P

最後,Linux 還可以使用 read 應用程序來暫停,等待按下回車鍵繼續執行。如果在指定時間內未按下回車鍵,則可以使用可選的超時參數繼續執行。

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

結論

如您所見,在腳本或命令行中暫停執行的方法有很多。根據您的需求,可能僅需一個簡單的 Start-Sleep 命令,或者一個更複雜的輸入驅動過程。結合本地命令,PowerShell 暫停可以在幾乎任何環境中實現靈活性和腳本效用的最大化。

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