web-dev-qa-db-ja.com

PowerShellの&&および||に相当するものは何ですか演算子?

Bashでは次のようなことが簡単にできます

command1 && command2 || command3

これは、command1を実行し、command1がcommand2の実行に成功した場合、およびcommand1がcommand3の実行に失敗した場合を意味します。

PowerShellの同等のものは何ですか?

35
Andrew J. Brehm

Bashが実行する必要があるのは、論理演算子に渡されるときに、コマンドの終了コードをブール値に暗黙的にキャストすることです。 PowerShellはこれを行いませんが、コマンドをラップして同じ動作を作成する関数を作成できます。

> function Get-ExitBoolean($cmd) { & $cmd | Out-Null; $? }

$?は最後の終了コードの成功を含むブール値です

与えられた2つのバッチファイル:

#pass.cmd
exit

そして

#fail.cmd
exit /b 200

...動作をテストできます:

> if (Get-ExitBoolean .\pass.cmd) { write pass } else { write fail }
pass
> if (Get-ExitBoolean .\fail.cmd) { write pass } else { write fail }
fail

論理演算子は、Bashと同じ方法で評価する必要があります。まず、エイリアスを設定します。

> Set-Alias geb Get-ExitBoolean

テスト:

> (geb .\pass.cmd) -and (geb .\fail.cmd)
False
> (geb .\fail.cmd) -and (geb .\pass.cmd)
False
> (geb .\pass.cmd) -and (geb .\pass.cmd)
True
> (geb .\pass.cmd) -or (geb .\fail.cmd)
True
10
James Kolpack

Update&&||がついにPowerShellに登場(コア)、つまりv7; RFC および この回答 を参照してください。
現時点では、GA 7.0バージョンでこれらの演算子がオプトインとして公開されるかどうかはわかりません 実験的機能 最初だけ。


質問が最初に出されてから何年も経って、要約させてくださいPowerShellv5.1の時点での状況

  • Bashの/ cmd&&および||制御演算子にはPowerShellに相当するものがありませんそしてPowerShellでカスタム演算子を定義できないため、適切な回避策はありません

    • 個別のコマンドを(個別の行で、または;で区切り)使用し、次のような自動変数$?を介して各コマンドの成功ステータスを明示的にテストします。
      command1 -arg1 -arg2; if ($?) { command2 -arg1 } # equivalent of &&
      command1 -arg1 -arg2; if (-not $?) { command2 -arg1 } # equivalent of ||

    • PowerShellの-and-orが一般的にnotソリューションである理由については、以下を参照してください。

  • ありました それらを追加することについて話しますしばらく前に、それはリストのトップに決してならなかったようです。

    • PowerShellがオープンソースになったので、an 問題はGitHubで開かれました
    • トークン&&||は現在、PowerShellで将来使用するために予約されているため、Bashと同じ構文を実装できることが期待されます。
      (PSv5.1以降、1 && 1のようなものを試行すると、エラーメッセージThe token '&&' is not a valid statement separator in this version.が生成されます)

PowerShellの-and-or&&||の代わりにならない理由:

Bashの制御演算子&&(論理ANDの短絡)および||(論理ORの短絡)暗黙的に終了コードでコマンドの成功ステータスを確認しますな​​し出力ストリームへの干渉;例えば。:

ls / nosuchfile && echo 'ok'

ls出力(stdout出力(/内のファイル)とstderr出力(存在しないファイルnosuchfileにアクセスしようとしたときのエラーメッセージ)の両方)はすべてパススルーされますただし、&&は、lsコマンドの(非表示の)exit codeをチェックして、echoコマンドが&&のRHSであるかどうかを判断します。制御演算子-実行する必要があります。

lsは終了コード1を報告します。この場合、failure-ファイルnosuchfileが存在しないため、-&&lsfailedそして、短絡を適用することにより、echoコマンドを実行する必要がないと判断します。
0bashの世界で成功を示すのは終了コードcmd.exeであるのに対し、nonzero出口コードは失敗を示すことに注意してください。

言い換えると、Bashの&&||はコマンドのoutputとは完全に独立して動作し、コマンドのsuccess statusにのみ作用します。


対照的に、PowerShellの-and-orは、コマンドの標準(成功)outputconsumeitにのみ作用します。 演算のブール結果のみを出力;例えば。:

(Get-ChildItem \, nosuchfile) -and 'ok'

上記:

  • を使用してsuccess(標準)出力(\のリスト)を消費し、それをBooleanとして解釈します;空でない入力コレクションは、ブールコンテキストでは$trueと見なされるため、少なくとも1つのエントリがある場合、式は$trueと評価されます。

    • ただし、エラーは別のストリームに送信されるため、存在しないファイルnosuchfileisに起因するerror情報は渡されます。
  • Get-ChildItem \, nosuchfileが空でない成功出力を返すとすると、LHSは$trueに評価されるため、-andもRHS'ok'を評価しますが、ここでも、Consumersの出力をブール値として解釈し、空でない文字列として、$trueにも評価されます。

  • したがって、-and式の全体的な結果は$trueであり、これは(唯一の成功)outputです。

正味の効果は次のとおりです。

  • -and式の両側からの成功出力は、評価中にusedであるため、事実上hidden

  • 式の唯一の(成功)出力はブール結果ですこれはこの場合は$trueです(英語システムの端末ではTrueとしてレンダリングされます)。

31
mklement0

[void]を使用してブール出力を非表示にし、副作用のみを取得する、このようなことを行うことができます。この場合、$ aまたは$ bがnullの場合、$ cが$ resultに割り当てられます。割り当ては式にすることができます。

$a = ''
$b = ''
$c = 'hi'

[void](
  ($result = $a) -or
  ($result = $b) -or
  ($result = $c))

$result

出力

hi
0
js2010

PowerShellで&&メソッドを使用する代わりに、try catchfinallyメソッドを使用できます。

try {hostname} catch {echo err} finally {ipconfig /all | findstr bios}
0
Cyberiron