web-dev-qa-db-ja.com

ifステートメントが常にfalseになるのはなぜですか?

このスクリプトを実行します。

if (Copy-Item .\test.ps1 $env:SystemRoot\System32)
{
    Write-Host "Done."
    exit 0
}
else
{
    Write-Host "Not done."
    Write-Host "You must be root."
    exit 1
}

このスクリプトを通常のユーザーとして実行すると、ルートではないため、elseステートメントでメッセージが表示されました。そして、これは大丈夫です。

しかし、このスクリプトをrootとして実行すると、elseステートメントにもメッセージが表示されます。ただし、ファイルのコピー操作は成功します。 ifステートメントでメッセージを取得できません。どうして?

エラーコードとその常にFalseも確認します。

28
Ahmet Mehmet

ifステートメントは、条件内のコマンドが正常に実行されたかどうかを評価しません。値(あなたの場合はコマンドの戻り値)のみをチェックし、boolにキャストします。

Copy-Item はデフォルトでは何も返さないため、[bool]$null$falseであるため、ifステートメントは常にfalseになります。

ここには3つのオプションがあります。

-PassThru パラメータを追加して、何らかの形式の戻り値を取得します。

if (Copy-Item .\test.ps1 $env:SystemRoot\System32 -PassThru)

$? 変数を使用して、前のコマンドが成功したかどうかを確認します。

Copy-Item .\test.ps1 $env:SystemRoot\System32
if ($?) {
    Write-Host "Done."
    exit 0
}
else {
    Write-Host "Not done."
    Write-Host "You must be root."
    exit 1
}

ただし、最も信頼できる方法は、それを Try {} Catch {} でラップして -ErrorAction Stop を追加することです。

Try {
    Copy-Item .\test.ps1 $env:SystemRoot\System32 -ErrorAction Stop
    Write-Host "Done."
    exit 0
}
Catch {
    Write-Host "Not done."
    Write-Host "You must be root."
    exit 1
}
80
SimonS