
Pipeline and chain operators (|| and &&) now in pwsh - nailer
https://github.com/PowerShell/PowerShell/pull/9849
======
rjmholt
Oh, this is my PR!

Also worth taking a look at the RFC[0] and the original issue[1].

Just to address some questions in the comments:

These operators had no equivalent in PowerShell previously, but they’d always
been planned from the outset. If you look at the diffs in the parser, one of
the things taken out is a comment where we parse `&&`/`||` saying something
like “we should implement this for v3” (I can’t seem to get a link on my phone
but don’t have a computer handy). In [1], mklement0 gives an excellent history
of the request for these operators. I owe a blog post on this, so hopefully I
can expand upon that.

Also, the pwsh/PowerShell thing exists partially because of needing to exist
side-by-side with Windows PowerShell and partially because it wasn’t always
clear that PowerShell 7 would be the direction of PowerShell into the future.

As a result, pwsh refers to PowerShell 6/7\. PowerShell 6 was called
PowerShell Core, but since PowerShell 7 has restored compatibility with a lot
of Windows functionality, we’ve dropped the Core for PowerShell 7. And since
PowerShell 5.1 and below are bound to Windows, they’re now qualified as
Windows PowerShell.

Finally, a lot of users call PowerShell `posh`, but that was already the name
of a shell in the Linux ecosystem, and after an early lesson with clobbering
native utilities with aliases on *nix, the PowerShell team wanted to be good
citizens.

Feel free to fire any questions at me too!

[0]: [https://github.com/PowerShell/PowerShell-
RFC/pull/192](https://github.com/PowerShell/PowerShell-RFC/pull/192) [1]:
[https://github.com/PowerShell/PowerShell/issues/3241](https://github.com/PowerShell/PowerShell/issues/3241)

~~~
nailer
`node` had something similar - there was already a package called `node` (I
think it was something to do with ham radio) on some distros.

Did you ever talk to the owner of `posh`? [https://www.commandlinux.com/man-
page/man1/posh.1.html](https://www.commandlinux.com/man-page/man1/posh.1.html)
Or think about using the `alternatives` system (which handles 'sendmail'
'node' and other shared names)?

~~~
rjmholt
(Sorry for the late response. Currently on vacation without a laptop.)

I wasn’t on the team when that change was made but I think it was discussed in
[0].

I’m not certain, but I suspect the reasoning went that a new name was needed
to not clash with `powershell.exe` but it wasn’t certain to be `posh`. So
unlike `node`, which had a clashing name from the outset, PowerShell never
used or owned `posh`, making the choice of `pwsh` a simpler way to avoid
clobbering another tool (and the subsequent complexity of the processes you
mentioned).

[0]:
[https://github.com/PowerShell/PowerShell/issues/4214](https://github.com/PowerShell/PowerShell/issues/4214)

------
geewee
I've had to implement quite a bit of powershell scripting in my new job. I've
always thought that their philosophy of "everything is an object" made sense,
but looking at powershell scripts has always somehow made my skin crawl,
probably because it's so different from years of ingrained bash scripting.

There's definitely a learning curve (and it's harder to find information
online), but once you get used to it, it's actually a pretty pleasant, cross-
platform scripting experience. I'd definitely say that I'm comfortable doing
more advanced scripts in powershell than I ever was in bash. If I had to use
anything more complex than a for-loop in bash, I would reach for a "proper"
programming language - but I can do quite a bit more in powershell without
having to switch.

~~~
userbinator
I think the verboseness is a huge turn-off for beginners --- it's like a mix
of C# and bash. The general prevalence of uppercase characters (I believe it's
case-insensitive like a lot of Windows things, so I don't really understand
why they had to capitalise words which are already hyphen-separated) also adds
to the overall "clumsy" look.

In contrast, bash scripting is basically entirely lowercase with very minor
exceptions.

~~~
OskarS
A notable thing about unix commands is that they're usually very short: "cd",
"ls", "grep", "sed", "cat", etc. This is obviously a remnant of earlier times,
but I actually think that it serves the unix command quite well even today.
These are commands you want to type quickly and many right after another.
Powershell's "Get-ChildItem" and "Select-String" are annoyingly verbose in
comparison.

~~~
shyn3
Get-ChildItem is gci. For Select-String I don't think there is a shorter
version. Many of the commands have shorter aliases they are just not as
intuitive.

/r/PowerShell is really helpful if you are stuck also there is a Slack POSH
group that is really helpful.

~~~
jodrellblank
"sls" is select-string.

Get-Alias to see them all. "get-alias -Definition Select-String" to look for
one for a specific command.

------
tasogare
Pwsh = Powershell. I use it from time to time yet the short name didn’t click
when I read title.

~~~
rudiv
I thought the short-form most people used was `posh`, personally, but I might
be wrong.

~~~
felixfbecker
pwsh is simply the name of the binary of PowerShell Core. They gave it a
different name to allow side-by-side installation, and to align with other
shells on *nix (sh, bash, zsh, fish, ...)

------
Riverheart
I'm not familiar with the usage of "pipeline" in this context. Could a kind
soul elaborate? These look like boolean operators to me.

~~~
unlinked_dll
Comes from unix. You "pipe" the output of one program to the input of another.
In unix shell scripts it's common to use `|` symbol for this in shells. It's
just a different paradigm of composing scripts that can be quite natural.

Chaining means you run one command followed by the other, so "&&" could be
read as "and then"

~~~
Riverheart
Right but Powershell has '|' for piping objects between commands. What does ||
do that the current operator doesn't support or is it just another way of
saying -or?

Edit: nvm, I see below these are emulating the behaviour expected from bash. I
guess it's called the pipeline operator because it uses the pipe symbol rather
than doing any piping.

~~~
rjmholt
In my RFC I dubbed them (&& and ||) the pipeline _chain_ operators because you
use them to chain syntactic pipelines together conditionally.

The POSIX shell spec calls them AND-OR lists, which I didn’t think was as
descriptive.

To explain the pipeline idea a bit better, there are two ways of seeing a
pipeline (in PowerShell or in a POSIX shell). One is at runtime; a command
executes, taking its input from an input and spitting it out to an output.
Chain a few commands together hooking the output of one to the input of
another and you have a pipeline. (In POSIX shells of course these in/out
locations are file descriptors, whereas in PowerShell they’re memory
locations.)

But also a pipeline can refer to the syntax of a pipeline; something like `ls
| grep “* .txt”` is a pipeline in terms of the POSIX shell grammar. Similarly
in PowerShell, `gci | ? Name -like “* .txt”` is a pipeline syntax. And since
you can chain these pipelines together with && and ||, I called the operators
“pipeline chain operators”.

BTW, if you ever want to look at the abstract syntax tree of a PowerShell
command, it’s very easy to do by wrapping it in a scriptblock and grabbing its
AST:

    
    
       $ast = { gi file.txt && rm file.txt }.Ast
       $ast.EndBlock.Statements[0]

~~~
Riverheart
Interesting. Thanks for the detailed response!

------
Narishma
I'm surprised these weren't supported until now. Or maybe they were with a
different syntax?

~~~
nizmow
First few lines of the link answers that question:

cmd1; if ($?) { cmd2 } = cmd1 && cmd2

cmd1; if (-not $?) { cmd2 } = cmd1 || cmd2

Just your usual Powershell verboseness.

~~~
tyingq
Their logical operators page says it also supports -and and -or. I can't tell
if _" cmd1 -and cmd2"_ would have already worked. It sounds like unadorned
"cmd1" didn't return the equivalent of $? before this PR.

~~~
jodrellblank
No it wouldn’t work, cmd1 would return the stdout output of cmd1 if you could
do that at all, but it would really try to use -and cmd2 as parameters to
cmd1.

~~~
tyingq
Interesting. Switching back and forth from Powershell and bash must be hard.
Also $? has the exact opposite meaning in a Unix shell. $? as zero indicates
success.

