Bashでは次のようなことが簡単にできます
command1 && command2 || command3
これは、command1を実行し、command1がcommand2の実行に成功した場合、およびcommand1がcommand3の実行に失敗した場合を意味します。
PowerShellの同等のものは何ですか?
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
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で将来使用するために予約されているため、Bashと同じ構文を実装できることが期待されます。1 && 1
のようなものを試行すると、エラーメッセージThe token '&&' is not a valid statement separator in this version.
が生成されます)-and
と-or
が&&
と||
の代わりにならない理由:Bashの制御演算子&&
(論理ANDの短絡)および||
(論理ORの短絡)暗黙的に終了コードでコマンドの成功ステータスを確認しますなし出力ストリームへの干渉;例えば。:
ls / nosuchfile && echo 'ok'
ls
出力(stdout出力(/
内のファイル)とstderr出力(存在しないファイルnosuchfile
にアクセスしようとしたときのエラーメッセージ)の両方)はすべてパススルーされますただし、&&
は、ls
コマンドの(非表示の)exit codeをチェックして、echo
コマンドが&&
のRHSであるかどうかを判断します。制御演算子-実行する必要があります。
ls
は終了コード1
を報告します。この場合、failure-ファイルnosuchfile
が存在しないため、-&&
はls
failedそして、短絡を適用することにより、echo
コマンドを実行する必要がないと判断します。0
とbash
の世界で成功を示すのは終了コードcmd.exe
であるのに対し、nonzero出口コードは失敗を示すことに注意してください。
言い換えると、Bashの&&
と||
はコマンドのoutputとは完全に独立して動作し、コマンドのsuccess statusにのみ作用します。
対照的に、PowerShellの-and
と-or
は、コマンドの標準(成功)output、consumeitにのみ作用します。 演算のブール結果のみを出力;例えば。:
(Get-ChildItem \, nosuchfile) -and 'ok'
上記:
を使用してsuccess(標準)出力(\
のリスト)を消費し、それをBooleanとして解釈します;空でない入力コレクションは、ブールコンテキストでは$true
と見なされるため、少なくとも1つのエントリがある場合、式は$true
と評価されます。
nosuchfile
isに起因するerror情報は渡されます。Get-ChildItem \, nosuchfile
が空でない成功出力を返すとすると、LHSは$true
に評価されるため、-and
もRHS'ok'
を評価しますが、ここでも、Consumersの出力をブール値として解釈し、空でない文字列として、$true
にも評価されます。
したがって、-and
式の全体的な結果は$true
であり、これは(唯一の成功)outputです。
正味の効果は次のとおりです。
-and
式の両側からの成功出力は、評価中にusedであるため、事実上hidden 。
式の唯一の(成功)出力はブール結果ですこれはこの場合は$true
です(英語システムの端末ではTrue
としてレンダリングされます)。
[void]を使用してブール出力を非表示にし、副作用のみを取得する、このようなことを行うことができます。この場合、$ aまたは$ bがnullの場合、$ cが$ resultに割り当てられます。割り当ては式にすることができます。
$a = ''
$b = ''
$c = 'hi'
[void](
($result = $a) -or
($result = $b) -or
($result = $c))
$result
出力
hi
PowerShellで&&メソッドを使用する代わりに、try catchfinallyメソッドを使用できます。
try {hostname} catch {echo err} finally {ipconfig /all | findstr bios}