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.
(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).
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.
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.
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.
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.
I absolutely love C#, and I also really like bash.
But powershell just looks so damned ugly to me! It's too verbose, and the idiomatic Pascal-Kebab-Case thing is just weird.
I know powershell has aliases for common things, like `ls` or `wget`, but your scripts are no longer cross-platform if you use them, as you'll use the powershell functions on Windows, but the Linux commands on Linux.
I've tried so hard to like it for so long, but I just... can't.
It does come with a ton of aliases to shorten up the names. I do find pwsh commands to be much more memberable than bash because of the verboseness and full named flags/switches.
I've become a massive fan of PowerShell. Getting used to using TAB-completion helps immensely, as do the aliases like you mentioned.
For TAB-completion I use MenuComplete instead of the default (Set-PSReadLineKeyHandler -Key Tab -Function MenuComplete) as it gives you IPython-like completion menus. With something like posh-git, it's amazing: you can type git checkout and then press TAB and have an interactive menu of the branches you can switch to; or if you've done a 'git status' you can then do git add, press TAB and you get a menu that intelligently shows you what files you might want to add.
> Pwsh = Powershell. I use it from time to time yet the short name didn’t click when I read title.
pwsh is typically used to refer to Powershell Core for generally confusing reasons (mostly that on Windows "classic" Powershell continues to exist and be supported for various Windows-only tasks).
kind of the whole point behind it was wanting to decouple the Powershell release cadence from that of Windows, getting updated versions of things in Windows is -hard-
Powershell 7 (which just dropped RC2) is the Powershell going forward, it's based on .NET Core, its xplat, it's the one with all the dev resources assigned to it
Windows Powershell ships with windows, and is still at 5.1 at last check
Powershell Core 6 will be the only major version of Powershell core, 7 drops the core moniker
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, ...)
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"
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.
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]
The problem is that many old utilities in Windows don't use the exit code to indicate failure. PowerShell cmdlets have exceptions that can be caught with `try`/`catch`, and there's `-ErrorAction Stop`, but there was no good solution for native commands.
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.
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.
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.
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 [1]: https://github.com/PowerShell/PowerShell/issues/3241