関数内で回復不可能なエラーが発生したときにPowerShell(PS1)スクリプトを終了する方法を探していました。例えば:
function foo() {
# Do stuff that causes an error
$Host.Exit()
}
もちろん$Host.Exit()
のようなものはありません。 $Host.SetShouldExit()
がありますが、これは実際にはコンソールウィンドウを閉じます。これは私が望むことではありません。私が必要としているのは、Pythonのsys.exit()
と同等のもので、これ以上の作業をせずに現在のスクリプトの実行を単純に停止することです。
編集: ええ、それはちょうどexit
です。ええと。
exit
キーワード を使用してください。
私はこれが古い投稿であることを認識していますが、それはこのトピックを検索する際のトップの検索結果の1つなので、私は自分自身がこのスレッドに戻ってくるのをよく感じます。しかし、私は矛盾する情報のせいで来たときより常に混乱しています。最終的に私はそれを把握するために私自身のテストを常に実行しなければなりません。そこで今回は私の調査結果を投稿します。
TL; DR ほとんどの人は、実行中のスクリプトを終了するためにExit
を使いたいと思うでしょう。しかし、あなたのスクリプトが単に後でシェルで使われる関数を宣言しているだけなら、その関数の定義の中でReturn
を使いたくなるでしょう。
終了: 現在実行中のコンテキストを「終了」します。スクリプトからこのコマンドを呼び出すと、スクリプトは終了します。シェルからこのコマンドを呼び出すと、シェルを終了します。
関数がExitコマンドを呼び出すと、実行中のコンテキストを終了します。したがって、その関数が実行中のスクリプト内からのみ呼び出された場合、そのスクリプトは終了します。ただし、現在のシェルから使用できるようにスクリプトが単にその関数を宣言してその関数をシェルから実行すると、シェルはExit
コマンドを含む関数が実行されているコンテキストであるため、シェルを終了します。
注: PowerShellでスクリプトを実行するためにスクリプトを右クリックした場合、デフォルトでは、スクリプトの実行が終了すると、PowerShellは自動的に閉じます。これはExit
コマンドやスクリプト内の他のものとは関係ありません。これは、スクリプトを実行するこの特定の方法を使用して実行されているスクリプトに対する単なるデフォルトのPowerShellの動作です。バッチファイルとコマンドラインウィンドウにも同じことが言えます。
Return: 前の呼び出しポイントに戻ります。スクリプトから(他の関数の外側で)このコマンドを呼び出すと、シェルに戻ります。シェルからこのコマンドを呼び出すと、シェルに戻ります(これは、シェルから実行された単一のコマンドの前の呼び出しポイントです)。関数からこのコマンドを呼び出すと、その関数が呼び出された場所に戻ります。
それが返された呼び出しポイントの後のコマンドの実行は、そのポイントから続行されます。スクリプトがシェルから呼び出され、関数の外側にReturn
コマンドが含まれていると、シェルに戻るときに実行するコマンドがなくなり、このように使用されるReturn
は基本的にExit
と同じになります。
中断: これによりループが中断され、ケースが切り替わります。ループやスイッチケースに入っていないときにこのコマンドを呼び出すと、スクリプトから抜けます。ループの内側にネストされているループの内側でBreak
を呼び出すと、呼び出されたループから抜け出すだけです。
ループの前にラベルを付けることができ、そのラベル付きループ内の複数のネストされたグループ内でBreak
コマンドが呼び出されても、そのラベル付きループから抜け出すことができるBreak
の興味深い機能もあります。
While ($true) {
# Code here will run
:myLabel While ($true) {
# Code here will run
While ($true) {
# Code here will run
While ($true) {
# Code here will run
Break myLabel
# Code here will not run
}
# Code here will not run
}
# Code here will not run
}
# Code here will run
}
Exit
もPowerShellを終了します。現在の関数やスクリプトから抜け出すには - Break
:)を使用してください。
If ($Breakout -eq $true)
{
Write-Host "Break Out!"
Break
}
ElseIf ($Breakout -eq $false)
{
Write-Host "No Breakout for you!"
}
Else
{
Write-Host "Breakout wasn't defined..."
}
Write-Error は非終了エラー用、 throw は終了エラー用です。
Write-Errorコマンドレットは、終了しないエラーを宣言します。デフォルトでは、エラーはエラーストリームでホストプログラムに送信され、出力とともに表示されます。
非終了エラーはエラーストリームにエラーを書き込みますが、それらはコマンド処理を停止しません。入力項目の集合内の1つの項目で非終了エラーが宣言されている場合、コマンドはその集合内の他の項目の処理を続けます。
終了エラーを宣言するには、Throwキーワードを使用します。詳細については、about_Throw( http://go.Microsoft.com/fwlink/?LinkID = 145153 )を参照してください。
このプロセスを終了して、基盤となるオペレーティングシステムに指定された終了コードを渡します。
https://msdn.Microsoft.com/ja-jp/library/system.environment.exit%28v=vs.110%29.aspx
[Environment]::Exit(1)
これにより、あなたは特定の終了コードで終了することができ、それは呼び出し側から拾うことができます。
Return
ではなくBreak
を探していると思います。中断は通常ループに使用され、最も内側のコードブロックからの中断のみです。関数やスクリプトを終了するにはReturnを使います。
特にエラーの理由を明確にしたい場合は、例外をスローするとよいでしょう。
throw "Error Message"
これにより終了エラーが発生します。
「トラップ」を使用した方が良いかもしれません。 PowerShellトラップは、終了またはエラーが発生したときに実行するコードブロックを指定します。タイプ
Get-Help about_trap
トラップステートメントの詳細をご覧ください。
私は偶然にBreak <UnknownLabel>
(例えば単にBreak Script
、 ラベルScript
が存在しない )がスクリプト全体から抜け出して(関数内からでさえ)現れていることを発見し、Hostを生き続けています。
このようにして、現在のスコープを知らずに(そしてラベルを作成することなく)どこからでもスクリプトを中断する関数(例えば再帰ループ)を作成することができます。
Function Quit($Text) {
Write-Host "Quiting because: " $Text
Break Script
}
私はこれをプログラムの再実行に使いました。それが役立つかどうかはわかりませんが、2つの異なるエントリしか必要としない単純なif文です。それは私にとってはPowerShellで機能しました。
$rerun = Read-Host "Rerun report (y/n)?"
if($rerun -eq "y") { Show-MemoryReport }
if($rerun -eq "n") { Exit }
これで効果があるかどうかはわかりませんが、実行した後でプログラムを終了させることになると思います。ただし、この場合、定義されたすべての入力には、一覧表示され分類された出力が必要です。また、出口で新しいプロンプト行を呼び出してプログラムをそのように終了させることもできます。