Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the PowerShell equivalents of Bash's && and || operators?

In Bash I can easily do something like

command1 && command2 || command3 

which means to run command1 and if command1 succeeds to run command2 and if command1 fails to run command3.

What's the equivalent in PowerShell?

like image 719
Andrew J. Brehm Avatar asked Mar 10 '10 12:03

Andrew J. Brehm


People also ask

What is equivalent in PowerShell?

Use gcm as the Equivalent of Which Command in PowerShell You can use the gcm alias as the equivalent of which command in PowerShell.

What is grep equivalent in PowerShell?

So you can think of Select-String as PowerShell version of Grep. The Select-String cmdlet searches for text and text patterns in input strings and files. You can use Select-String similar to grep in UNIX or findstr in Windows.

Are PowerShell commands the same as Linux?

Being a cross-platform scripting language, PowerShell on Linux supports all of the commonly known commands from CMD and Linux's command line shell such as sudo apt update . No need to open a Bash terminal! From here on out you can run thousands of built-in PowerShell commands.

Is PowerShell as powerful as Bash?

At the end of the day, comparing PowerShell to Bash is like comparing apples to oranges. Both are tools for different jobs. If you are managing a Windows environment or using Azure, try sticking with PowerShell. If you are managing a strictly Linux or Unix environment, try sticking with Bash.


1 Answers

Update: && and || have finally come to PowerShell (Core), namely in v7; see this answer.


Many years after the question was first asked, let me summarize the state of affairs as of PowerShell v5.1:

  • Bash's / cmd's && and || control operators have NO PowerShell equivalents, and since you cannot define custom operators in PowerShell, there are no good workarounds:

    • Use separate commands (on separate lines or separated with ;), and explicitly test the success status of each command via automatic variable $?, such as:
      command1 -arg1 -arg2; if ($?) { command2 -arg1 } # equivalent of &&
      command1 -arg1 -arg2; if (-not $?) { command2 -arg1 } # equivalent of ||

    • See below for why PowerShell's -and and -or are generally not a solution.

  • There was talk about adding them a while back, but it seemingly never made the top of the list.

    • Now that PowerShell has gone open-source, an issue has been opened on GitHub.
    • The tokens && and || are currently reserved for future use in PowerShell, so there's hope that the same syntax as in Bash can be implemented.
      (As of PSv5.1, attempting something like 1 && 1 yields error message The token '&&' is not a valid statement separator in this version.)

Why PowerShell's -and and -or are no substitute for && and ||:

Bash's control operators && (short-circuiting logical AND) and || (short-circuiting logical OR) implicitly check the success status of commands by their exit codes, without interfering with their output streams; e.g.:

ls / nosuchfile && echo 'ok' 

Whatever ls outputs -- both stdout output (the files in /) and stderr output (the error message from attempting to access non-existent file nosuchfile) -- is passed through, but && checks the (invisible) exit code of the ls command to decide if the echo command - the RHS of the && control operator - should be executed.

ls reports exit code 1 in this case, signaling failure -- because file nosuchfile doesn't exist -- so && decides that ls failed and, by applying short-circuiting, decides that the echo command need not be executed.
Note that it is exit code 0 that signals success in the world of cmd.exe and bash, whereas any nonzero exit code indicates failure.

In other words: Bash's && and || operate completely independently of the commands' output and only act on the success status of the commands.


PowerShell's -and and -or, by contrast, act only on the commands' standard (success) output, consume it and then output only the Boolean result of the operation; e.g.:

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

The above:

  • uses and consumes the success (standard) output -- the listing of \ -- and interprets it as a Boolean; a non-empty input collection is considered $true in a Boolean context, so if there's at least one entry, the expression evaluates to $true.

    • However, the error information resulting from nonexistent file nosuchfile is passed through, because errors are sent to a separate stream.
  • Given that Get-ChildItem \, nosuchfile returns non-empty success output, the LHS evaluated to $true, so -and also evaluates the RHS, 'ok', but, again, consumes its output and interprets it as a Boolean, which, as a nonempty string, also evaluates to $true.

  • Thus, the overall result of the -and expression is $true, which is (the only success) output.

The net effect is:

  • The success output from both sides of the -and expression is consumed during evaluation and therefore effectively hidden.

  • The expression's only (success) output is its Boolean result, which is $true in this case (which renders as True in the terminal).

like image 159
mklement0 Avatar answered Sep 30 '22 21:09

mklement0