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という2つのシンプルな入力があります。SecondsはSystem.Double数値値を取り、millisecondsはSystem.Int32値のみを取ります。これら2つを組み合わせることで、一時停止の長さを正確に制御することができます。また、Start-Sleepsleepという別名も持っています。

Start-Sleep -Seconds 2 -Milliseconds 300

PowerShell 6.2.0以前では、上記のコードで一時停止するために使用している2.3のような小数点以下の秒数を書くことはできませんでした。しかし、6.2.0以降では小数点以下の値もサポートされるようになりました。そのため、秒数とミリ秒を個別に記述する代わりに、-Seconds 2.3と記述することができます。

Start-Sleep関数からCtrl-Cを使用して抜けることができることを覚えておくことが重要です。これはすべてのメソッドには当てはまりません!

スレッドの休止

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)

Thread Sleepメソッドを使用するためには、次のようにします:

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

スレッドを無期限に一時停止するには、[System.Threading.Timeout]::InfiniteTimeSpanを使用しますが、これによってプロセスがロックされる可能性があることに注意してください。

Start-Sleepとは異なり、Thread SleepメソッドではCtrl-Cを使用して一時停止ルーチンを中断することはできません。アプリケーションによっては、これが好ましい場合もあります。

また、スレッドの休止について知っておくべき重要な点は、それが正確な時間保証ではないということです。すべてのスレッドの休止は、少なくとも指定した秒数待機することを保証します。スレッドの休止はクロックのティックと一致するため、他のプログラムによってこの一時停止関数が割り込まれ、待機時間が長くなることがあります。

スレッドの休止には使い道がありますが、これらの問題のため、他の組み込みメソッドの使用がより良いです。

Read-Host

上記の方法は、実行を一時停止する方法を説明していますが、一定の時間だけです。実行を一時停止するもう一つの方法は、ユーザーからの入力を求めることです。この方法では、手動のアクションが必要ですが、続行するための確認を要求し、追加の入力を含めることができるため、非常に便利です。

Read-Hostは、ユーザーからの入力を促すための最も一般的な方法の一つです。ユーザーからの入力を促すことにより、入力結果をコード内でさらに使用するために保存したり、必要に応じて実行を一時停止したりすることができます。

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

テキストが入力されたら、enterキーまたはreturnキーを押して実行を進める必要があります。変数に入力を保存せずにこれを行うと、入力された同じテキストがコンソールに出力されます。

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オブジェクトとして画面にエコーバックされます。これにはKeyKeyChar、およびModifiersの値が含まれており、特定のキーコンビネーションをチェックする際に非常に便利です。

[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は入力から抜け出せませんのでご注意ください。

Host RawUI ReadKey メソッド

最後に、$host.UI.RawUI.ReadKey() メソッドがあります。これは Console ReadKey メソッドに似ていますが、このメソッドでは ReadKey メソッドに追加のオプションを渡すことで動作や出力を制御することができます。

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

RawUI ReadKey メソッドをより有用にするために渡すことができるいくつかの ReadKeyOptions があります。

  • AllowCtrlC
  • IncludeKeyDown
  • IncludeKeyUp
  • NoEcho

以下のように使用することができ、キーのダウンイベントを含み、テキストをエコーしないようにすることができます。

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

このメソッドはコマンドから抜け出すためにCtrl-Cを使用することができますが、AllowCtrlC オプションが使用されている場合は除きます。

ネイティブでないメソッド

このセクションでは、スクリプトの実行を一時停止するためのいくつかのネイティブでないメソッドを探求します。これらのメソッドは、必要に応じて PowerShell スクリプトに統合できる非 PowerShell コンソール固有のユーティリティを利用することを意図しています。

Windows

Pause

一時停止コマンドは非常にシンプルで、Press any key to continue . . .と表示され、キーが押されるまで実行が再開されるまでそのまま表示されます。

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コマンドは任意の値でスリープを設定することができます。pauseコマンドとは異なり、sleepコマンドにはスリープ時間の柔軟性を提供するいくつかのオプションがあります。

sleep 2.3s
Sleep Command

sleepコマンドには、より長い時間を定義するための接尾辞もオプションで使用することができます。例:

  • sleep 1m – 1分間のスリープ
  • sleep 2h – 2時間のスリープ
  • sleep 1d – 1日間のスリープ

Read -P

また、Linuxはreadアプリケーションを使用して実行を一時停止することもできます。指定した時間内にEnterキーが押されない場合、オプションのタイムアウトパラメーターにより実行が続行されます。

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

結論

ご覧の通り、スクリプトやコマンドライン内で実行を一時停止する方法は多岐にわたります。必要に応じて、Start-Sleepコマンドやより複雑な入力駆動プロセスを使用することもできます。ネイティブコマンドと組み合わせることで、PowerShellの一時停止機能はほぼどんな環境でも柔軟に利用でき、スクリプトの有用性を最大限に引き出すことができます。

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