スクリプトの実行を一時停止する理由はさまざまです。スクリプトがユーザーの入力を待つ必要がある場合、実行速度を遅くする必要がある場合、または他のプロセスが終了するのを待つ必要がある場合などがあります。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-Sleep
はsleep
という別名も持っています。
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:
Thread Sleepメソッドを使用するためには、次のようにします:
スレッドを無期限に一時停止するには、[System.Threading.Timeout]::InfiniteTimeSpan
を使用しますが、これによってプロセスがロックされる可能性があることに注意してください。
Start-Sleep
とは異なり、Thread SleepメソッドではCtrl-C
を使用して一時停止ルーチンを中断することはできません。アプリケーションによっては、これが好ましい場合もあります。
また、スレッドの休止について知っておくべき重要な点は、それが正確な時間保証ではないということです。すべてのスレッドの休止は、少なくとも指定した秒数待機することを保証します。スレッドの休止はクロックのティックと一致するため、他のプログラムによってこの一時停止関数が割り込まれ、待機時間が長くなることがあります。
スレッドの休止には使い道がありますが、これらの問題のため、他の組み込みメソッドの使用がより良いです。
Read-Host
上記の方法は、実行を一時停止する方法を説明していますが、一定の時間だけです。実行を一時停止するもう一つの方法は、ユーザーからの入力を求めることです。この方法では、手動のアクションが必要ですが、続行するための確認を要求し、追加の入力を含めることができるため、非常に便利です。
Read-Host
は、ユーザーからの入力を促すための最も一般的な方法の一つです。ユーザーからの入力を促すことにより、入力結果をコード内でさらに使用するために保存したり、必要に応じて実行を一時停止したりすることができます。
テキストが入力されたら、enterキーまたはreturnキーを押して実行を進める必要があります。変数に入力を保存せずにこれを行うと、入力された同じテキストがコンソールに出力されます。

後で使用するために、入力されたテキストを変数に保存したい場合は、単純にRead-Host
の入力を変数に割り当てます。
時には、入力をセキュアな文字列として読み取りたい場合があります。幸いにも、Read-Host
を使用すると、これが非常に簡単になります。
Ctrl-C
を押すことで、Read-Host
のプロンプトから抜けることができます。
Console ReadKey メソッド
[Console]::ReadKey()
メソッドを使用すると、プログラムの実行を一時停止しながらキーコマンドと修飾子を簡単に読み取ることができます。デフォルトでは、送信されたキーコマンドはSystem.ConsoleKeyInfo
オブジェクトとして画面にエコーバックされます。これにはKey
、KeyChar
、およびModifiers
の値が含まれており、特定のキーコンビネーションをチェックする際に非常に便利です。

継続的に進む前に特定のキー入力をチェックしたい場合は、以下のようにDo-While
ループを使用することができます。

ここでは特定のキーの組み合わせを探しているため、
Ctrl-C
は入力から抜け出せませんのでご注意ください。
Host RawUI ReadKey メソッド
最後に、$host.UI.RawUI.ReadKey()
メソッドがあります。これは Console ReadKey メソッドに似ていますが、このメソッドでは ReadKey メソッドに追加のオプションを渡すことで動作や出力を制御することができます。

RawUI ReadKey メソッドをより有用にするために渡すことができるいくつかの ReadKeyOptions
があります。
AllowCtrlC
IncludeKeyDown
IncludeKeyUp
NoEcho
以下のように使用することができ、キーのダウンイベントを含み、テキストをエコーしないようにすることができます。
このメソッドはコマンドから抜け出すために
Ctrl-C
を使用することができますが、AllowCtrlC
オプションが使用されている場合は除きます。
ネイティブでないメソッド
このセクションでは、スクリプトの実行を一時停止するためのいくつかのネイティブでないメソッドを探求します。これらのメソッドは、必要に応じて PowerShell スクリプトに統合できる非 PowerShell コンソール固有のユーティリティを利用することを意図しています。
Windows
一時停止コマンドは非常にシンプルで、Press any key to continue . . .
と表示され、キーが押されるまで実行が再開されるまでそのまま表示されます。

スクリプトでこれを使用する方法について質問するかもしれませんが、他のコマンドと同様に、ネイティブの機能を利用するためにスクリプト内にcmd /c 'pause'
コマンドを挿入します。

通常、Windowsのバッチファイルで使用されるtimeoutコマンドは、指定された秒数だけ一時停止し、任意のキーコマンドを無視することができます。通常、タイムアウト期間が経過していなくても、ユーザーのキーストロークによって実行が再開されます。秒数を渡すことで非常に簡単に使用できます。

pause
コマンドと同様に、スクリプト内にtimeout
コマンドを挿入し、以下の例ではエンターキーを押して続行します。

Linux
Windowsのpause
コマンドと同様に、Linuxのsleep
コマンドは任意の値でスリープを設定することができます。pauseコマンドとは異なり、sleepコマンドにはスリープ時間の柔軟性を提供するいくつかのオプションがあります。

sleep
コマンドには、より長い時間を定義するための接尾辞もオプションで使用することができます。例:
sleep 1m
– 1分間のスリープsleep 2h
– 2時間のスリープsleep 1d
– 1日間のスリープ
また、Linuxはread
アプリケーションを使用して実行を一時停止することもできます。指定した時間内にEnterキーが押されない場合、オプションのタイムアウトパラメーターにより実行が続行されます。

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