I used bash in college and then didn’t use it for around 5 years. And then I used powershell.
And bash is still a lot better as a shell language. Powershell commands are long and annoying. If you remember all the aliases (most of which are annoyingly bash commands but hardly behave that way) then the parameters are long and annoying.
Stringing commands together requires too much API digging because objects mean you need to run a variety of incantations on the results to know what members you need to pull out and what data format they have, etc. in Bash it’s always strings and if you know a couple of useful string manipulation commands such as cut, that you probably know anyways for other reasons, you can get by with stringing most commands fairly trivially.
Powershell OTOH is a lot better when I’m trying to write an actual reusable script. But at that point why wouldn’t I just use something like Python anyways (or if it will be associated with a front end repo I will often just use nodejs since it’s definitely installed). Python has much more usable comparison, control flow, etc operators, much bigger libraries, better multi OS compatibility etc.
The only advantage really is using powershell commands/applications, so sometimes I will write my scripts in Powershell.
But in Linux I will also sometimes write my scripts in bash for the same reason, so it’s not really an advantage inherent to powershell, but the fact that it’s the “standard” of the OS.
I do like Powershell, but the problem with it is that it tried to be both a great scripting language and a great shell language, but the things that make it a good scripting language, such as verbose naming, objects, etc make it a worse shell language than shell languages designed to be shell languages first, and the things that it does to make it a useable shell language, makes it a worse scripting language than other scripting languages.
On average it may be the best language across all environments and use cases. The problem is that for any specific environment and use case it’s rarely one of the better languages.
I'm not sure I understand your point regarding having to look at the output of commands to know how to use them. At least with Powershell you have tab-completion suggesting your object members; you have to at least look at whatever flavor of semi-parsable text is coming from your command in bash to use cut or awk or whatever on it (and the semantics of what you're looking at are not discoverable, so you're likely to have to some API digging of your own). 'cut' and the like is sadly fragile for a number of reasons, and you generally won't discover them in advance (e.g. when the date "field" starts containing a year, sizes overflow or start being indicated with human-readable abbreviations after a threshold, which is exactly the sort of thing you can't tell by inspection). And bash's failure modes are really sharp.
To be honest, something like
$titled = gci *.md| ?{ (gc $_)[0] -like '# *' }
seems short and less error-prone than the bash equivalent. Not sure what it would be. Something like
titled=(); for file in *.md; do if head -1 "${file}" | grep -sq '^# .*'; then titled+=("${file}"); fi; done
I think there's a lot of little gotchas in there, and not a little "API digging" for options, though it's simple in concept.
> you have to at least look at whatever flavor of semi-parsable text is coming from your command in bash to use cut or awk or whatever on it
Having to parse things is definitely a pain, at least until you get good at it. But the critical thing is that all the output is right there on the screen, and often in a format that's at least somewhat designed to be parsed. In PowerShell you have to go diving through the object hierarchy. That would be OK I guess if things were intuitive and the help and documentation were great but that's often not the case. And often the API semantics are designed for a different language altogether (C#) and the things you have to do to consume the API in PowerShell are ugly.
Your "diving through object hierarchy" has a _consistent_ command called "Get-Member". Not the same where you need to dive through several hundred text output structures for different commands and/or read man page options. I am sorry, but your statement is factually false.
The simplest technique for analyzing the objects that a command returns is to pipe the output of that command to the Get-Member cmdlet. The Get-Member cmdlet shows you the formal name of the object type and a complete listing of its members.
This is a very succinct dissection of the problems but I will add one more: PowerShell's frustrating behavior where any return value of a function call is part of the enclosing function's return value if not explicitly swallowed. I understand what they were going for by analogy with other shells here, but in my opinion in a language like PowerShell (with actual return values) this is unintuitive and makes it really easy to introduce bugs. The whole object pipeline thing they were going for feels like an evolutionary dead end that we shouldn't be saddled with.
I agree, this is a place where the desired features are in tension. I will say that it took me a while to find it, and I don't find it limiting now that I understand it, but it was a real gotcha when I encountered it.
And bash is still a lot better as a shell language. Powershell commands are long and annoying. If you remember all the aliases (most of which are annoyingly bash commands but hardly behave that way) then the parameters are long and annoying.
Stringing commands together requires too much API digging because objects mean you need to run a variety of incantations on the results to know what members you need to pull out and what data format they have, etc. in Bash it’s always strings and if you know a couple of useful string manipulation commands such as cut, that you probably know anyways for other reasons, you can get by with stringing most commands fairly trivially.
Powershell OTOH is a lot better when I’m trying to write an actual reusable script. But at that point why wouldn’t I just use something like Python anyways (or if it will be associated with a front end repo I will often just use nodejs since it’s definitely installed). Python has much more usable comparison, control flow, etc operators, much bigger libraries, better multi OS compatibility etc.
The only advantage really is using powershell commands/applications, so sometimes I will write my scripts in Powershell.
But in Linux I will also sometimes write my scripts in bash for the same reason, so it’s not really an advantage inherent to powershell, but the fact that it’s the “standard” of the OS.
I do like Powershell, but the problem with it is that it tried to be both a great scripting language and a great shell language, but the things that make it a good scripting language, such as verbose naming, objects, etc make it a worse shell language than shell languages designed to be shell languages first, and the things that it does to make it a useable shell language, makes it a worse scripting language than other scripting languages.
On average it may be the best language across all environments and use cases. The problem is that for any specific environment and use case it’s rarely one of the better languages.