PowerShellにおける$?変数は、直前に実行したコマンドの成功または失敗を示す自動変数です。
PowerShellのスクリプトやコマンドの中で、その成否を確認して、次の処理を制御する場合に便利です。
- 成功した場合、
$?はTrueを返します。 - 失敗した場合、
$?はFalseを返します。
この記事では、$?の基本的な使い方から、実際のサンプルスクリプトを通して、どのようにエラーハンドリングに利用できるかを説明します。
基本的な使い方
$?は、直前に実行されたコマンドの実行結果に基づいて値を返します。
以下の簡単な例で、コマンドが成功したかどうかを確認します。
Get-Process
# プロセスの取得が成功した場合、$?はTrueを返す
Write-Output "コマンド成功: $?"
上記の例では、Get-Processコマンドはプロセスの一覧を取得し、成功した場合は$?がTrueとなります。
Write-Outputでその結果が表示されます。
コマンドが失敗した場合の例
次に、意図的に存在しないコマンドを実行して、失敗した場合の$?の値を確認してみましょう。
Get-FakeCommand
# このコマンドは存在しないため、$?はFalseを返す
Write-Output "コマンド成功: $?"
この例では、Get-FakeCommandという無効なコマンドを実行しているため、PowerShellはエラーを出力し、$?はFalseを返します。
$?を使ったエラーハンドリング
$?は、スクリプト内でエラーが発生したかどうかを確認し、その後の処理を制御するためにも使用できます。
次の例では、コマンドが成功した場合と失敗した場合で、異なるメッセージを表示します。
Get-Process
if ($?) {
Write-Output "プロセス情報を正常に取得しました。"
} else {
Write-Output "プロセス情報の取得に失敗しました。"
}
複数のコマンドを扱う場合の注意点
$?は常に直前に実行されたコマンドの結果を返すため、複数のコマンドを一度に実行する場合は注意が必要です。
以下の例では、$?がどのコマンドに対して結果を返しているのかを確認してみます。
Get-Process
Write-Output "1回目の成功判定: $?"
Get-FakeCommand
Write-Output "2回目の成功判定: $?"
この場合、最初のWrite-OutputはGet-Processの結果を表示し、2回目のWrite-OutputはGet-FakeCommandの結果を表示します。
それぞれのコマンドの成否を適切に確認できるよう、直後に$?をチェックすることが重要です。
エラーハンドリングの実践例
次に、複数のコマンドを実行し、それぞれのコマンドの成功・失敗に基づいて処理を分岐する実践的なスクリプトの例を示します。
# ファイルのコピーを試みる
Copy-Item -Path "C:\source\file.txt" -Destination "C:\destination"
if ($?) {
Write-Output "ファイルのコピーに成功しました。"
} else {
Write-Output "ファイルのコピーに失敗しました。次のステップに進みません。"
# エラーが発生したのでスクリプトを終了
exit
}
# 次の処理
Write-Output "次の処理を開始します。"
この例では、Copy-Itemコマンドの成功を$?で確認し、失敗した場合はエラーメッセージを表示してスクリプトを終了します。成功した場合のみ次の処理に進みます。
注意点
- $?は最後のコマンドにのみ適用される
$?は、最後に実行したコマンドの結果しか保持しません。これにより、複数のコマンドが続く場合は、それぞれの成否を確認するために個別にチェックする必要があります。 try/catchとの併用$?は単純なエラーチェックには便利ですが、詳細なエラーハンドリングが必要な場合は、try/catch構文と併用することをお勧めします。
まとめ
PowerShellの$?変数を使用すると、直前のコマンドが成功したかどうかを簡単に確認できます。$?を活用することで、スクリプトのエラーハンドリングが簡潔に行えるため、スクリプトの信頼性が向上します。