Hacker News new | past | comments | ask | show | jobs | submit login
A Saner Windows Command Line (futurice.com)
147 points by japaget on March 30, 2016 | hide | past | favorite | 161 comments



To hear bash-people to call Powershell "non-intuitive" sounds like those immigrants that go to a foreign land, refuse to learn the local language and insist on the natives to understand their immigrant language. Or like programmers that think that every programming language should have the C syntax.

Bash and Unix commands are only "intuitive" after years of practice; Powershell is not different. And it doesn't have any obligation of being equal to bash.


I am a big fan of Powershell, yet...and there had to be a "yet", now didn't there?...the Bash based criticism is well grounded even if not always perfectly articulated.

I see it this way, the great thing about Powershell commands is that I get back an object. The great thing about Bash commands is that I get back text. The object is great because I don't have to parse it. The text is great because I can parse it.

The downside of Powershell is that if I don't have technical expertise in regard to the object a command returns, I have to go read deep into a manual to figure how I can do something simple. The downside of Bash is that if I have deep technical expertise about the text that is returned, I still have to parse it as text to do something simple.

The high level abstractions of Powershell are better suited for dealing with known processes and contexts where I care about the semantics of the returned value. The low level abstraction of text is better for dealing with unknown processes and contexts where I don't really care about the semantics of the value.


I've never used Powershell.

Is it possible for Powershell to output the object as JSON so that you can see what you can read from the object?


In the world of Powershell, reflection would be the way to go because then I still have an object. A rough analogy would be the window object in Javascript where I call `window.open(something)` directly. Serializing a value returned by a Powershell command to JSON eliminates being able to call `returned_value.some_method(something)` because converting it into JSON puts me in the world of text and parsing.

At that point, I either know the name of the method I'm looking for or I don't. In the first case the conversion to JSON doesn't do me any good because I can just call the method directly using `object.method(value)`. In the second case, it doesn't do any good because I don't know the method I want.

Reflection looks more like this: http://stackoverflow.com/questions/9952391/use-get-member-fo...


dir | ConvertTo-Json

dir | ConvertTo-Html

dir | ConvertTo-Xml

dir | ConvertTo-Csv


Things I like about PowerShell include objects - cmdlets return them and you can call methods. For example, you can get a list of services (get-service) and each is a ServiceController object, which you can Start(), Stop(), etc.

Things I don't like, or is a pain point for me, are those same objects. As far as I can tell, there isn't a better way to figure out what you actually are getting back from a cmdlet besides feeding output through Get-Member.

For example, what comes back from dir/ls/Get-ChildItem? Well that's a trick question because it depends on which "provider" you invoke. On a file system (dir somedirectory) you'll get back FileInfo or Directory info, for a registry hive (dir hklm:) you'll get a RegistryKey, for environment variables (dir env:) you get a DictionaryEntry, etc.

So while it is fantastic there is a general way to enumerate items, the docs have to be vague and list System.Object as what returns from Get-ChildItem and its various aliases, which isn't very useful for working with the results.

This makes forming non-trivial commands with pipelines fairly annoying because I have to feed each stage through Get-Member to even figure out what I have and what is now available; this strategy starts to break down if a pipeline stage feeds a loop, etc.

I'd love it if the ISE displayed what actual object type exists at every point of a pipeline, rather than the trial-and-error-by-Get-Member approach I've adopted. Or for there to be some better way to get the return type of a cmdlet.

PowerShell is a huge improvement over the old command prompt though.


> what comes back from dir/ls/Get-ChildItem?

If you look at the note properties that get added to the objects, they're consistent across providers:

PS C:\> (Get-Item c:\).PSPath

Microsoft.PowerShell.Core\FileSystem::C:\

PS C:\> (Get-Item env:username).PSPath

Microsoft.PowerShell.Core\Environment::username

PS C:\> (Get-Item HKLM:\software).PSPath

Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\software

There's also some magic that you can do with tab completion to see the properties. For example, if you type...

(Get-ChildItem c:\ | sort).

...and hit tab, you can tab through the list of properties of the objects returned by Get-ChildItem when it's used on the FileSystem provider. (Don't ask me how the hell that works, though...)


Windows fanboy here. Powershell made the mistake of combining a bad command prompt with a bad scripting language. It is not a "shell" at all. It is bad Python.

The excessive verbosity and object safety is great for admin scenarios where you don't suddenly destroy your corporate email transition because of a VP with an apostrophe in her name. But at that point perhaps you should just use C# instead?

But for everything else it just looks nuts to outsiders. That's why even the MS developer groups are releasing command line tools cross-platform that behave like Unix apps, not PS monstrosities.

https://azure.microsoft.com/en-us/documentation/articles/xpl...

Powershell should be a feature that draws people from AWS. Instead it is seen as a drawback, even inside MS.


Simply stating something is bad, without anything to back it up, doesn't make it bad.

Learn some alias's if you don't like the Get-X style of functions.

gal * | more

Will list tons of alias's for you.


Got a directory full of files with underscores in the names? Want spaces instead? Easy, type this:

dir -recurse | where {-Not $_.PsIscontainer -AND $_.name -match "_"} | foreach { $New=$_.name.Replace("_"," ") Rename-Item -path $_.Fullname -newname $New -passthru }

EDIT: I purposely posted the first Google result. You obviously Googled as well as your code got it backward. But really, why isn't it this? It's worked since the 1980s. You'll dig it since it uses extra apostrophes.

    rename '_' ' ' *


Dir | rni –NewName { $_.name –replace " ","_" }

That command does some extra stuff, which would make the bash equivalent also complicated.


Yep. Technically the request included recursive rename, and to avoid renaming directories, but gosh that's not hard:

    dir -rec -file | rni –newname { $_.name –replace "_"," " }
Edit: Oops, request did not include recursive, the original sample solution did.

FWIW top Google results for "unix recursively rename files" give below solutions (slightly different scenarios but you get the idea). Not particularly shorter, or less cryptic:

    find . -iname "*dbg*" -exec rename _dbg.txt .txt '{}' \;

    shopt -s globstar nullglob
    rename _dbg.txt .txt **/*dbg*


His 'rename' wasn't recursive.

<Quote>Y'all are still missing the point. We live in a world where people use CoffeeScript to avoid typing a semicolon. When you Google a PowerShell problem the Google results come back looking insane. You can play code golf here all you want but even this version looks nuts to outsiders

It's a cultural problem. You don't solve it by shouting subtly-differing versions of your culture, louder. ".</Quote>

You're not getting the point. Powershell is just short, and sometimes shorter if you actually learn it.

"When you Google a PowerShell problem the Google results come back looking insane" - This is a problem with the age of powershell. Bash has been around for ever, so there is lots of good quality content on the web.


Y'all are still missing the point. We live in a world where people use CoffeeScript to avoid typing a semicolon.

When you Google a PowerShell problem the Google results come back looking insane. You can play code golf here all you want but even this version looks nuts to outsiders.

It's a cultural problem. You don't solve it by shouting subtly-differing versions of your culture, louder.


That wasn't what I Googled. And Microsoft is announcing bash and Linux shell subsystems today for Windows so y'all are really missing the point. Maybe dev goes one way and ops goes another. But probably not. I'm not betting on Powershell.


"You obviously Googled as well as your code got it backward. " - No, just a simple mistake from writing it on the fly.

This isn't even probably the smallest, somebody smarter than me could do better.

There's probably a PowerShell module that has your equivalent.


In my view they should have made Powershell as a language that's derived from C#. Or they should have stuck to bash. Both approaches could have worked. Instead it's that weird thing in the middle that doesn't do anything really right.


I've just recently gone back to using Windows 10 after being a heavy XP user. I think Powershell is perfectly fine... for my uses up to now there's always a tutorial online to help. And some commands are the same between shells so I wasn't completely lost :/


Powershell and its long winded cmdlets are really hard for me to like. I always fall back to cygwin on windows.

I once wrote a PS script to set some power management options on a corporate laptop. The script was 11 lines long (vs 3 lines in Python), it was harder to read and understand. Even with ISE available it was much harder to write.

I followed along with some exchange server tutorial where the prescribed easy way to achieve the task was a completely unintuitive PS script. I kept thinking about how much easier that particular config change was to make on a Linux host running postfix.

I can't see what benefit PS has over cygwin bash but I'd love to hear ideas because PS comes installed out of the box where I have to install cygwin myself.


PowerShell obeys the first iron law of I/O: ALL data has a type. Bash (and Unix in general) -- does not.

Now of course the implementation of typed pipelines in PowerShell is clunky and forced, because typed I/O primitives do not (yet) actually exist in Windows, so all the piping is done within one process with streams of object pointers, else it doesn't work. There are other problems, too: I recall one advocate linking me to the PowerShit solution to some admin task like changing the ACLs of a directory tree recursively. It involved including a C# program as a herestring, passing it to the C# compiler, and loading the resulting bytecode. The advocate said "Isn't this beautiful and elegant?"

But in principle the model embraced by PowerShell is strictly more robust than bash's fragile "dumb byte pipes" model.

"Get a byte, get a byte, get a byte, byte, byte!" --NT architect Dave Cutler, on Unix I/O


And the UNIX style has a cost: It is insecure e.g. [0][1].

Luckily modern UNIX-based systems are rarely used as multi-user terminals these days or we would see many more privilege escalations via exploiting bugs in scripts which iterate over user owned files. Even in web scenarios, most web frameworks carefully manage what is allowed in a filename or set the filename themselves.

Ultimately because on UNIX there is no type, you have to make assumptions. These assumptions are sometimes dangerously wrong. You can definitely write scripts and execute commands in a more secure way, but you can go google Linux tutorials right now and find tons of examples where newbies are taught to do it wrong out of the gate.

Data types make this "secure by default." String for everything requires the script-writer or command line-writer to be perfect every time they hit return.

[0] http://www.defensecode.com/public/DefenseCode_Unix_WildCards... [1] https://www.helpnetsecurity.com/2014/06/27/exploiting-wildca...


Bash scripts aren't usually intended to be secure. They're quickly written one-offs that do some tiny task and do it well, not usually exposed to an insecure environment or externally controlled input.

If you want to write a good program, use a programming language that cares about good programming. Bash et al. don't care about how good the program is, they care about getting something done quick.


Well, that's what we thought before the ShellShock vulnerability ended up being a major security worry due to all of the places that bash scripts end up being used.


Bash doesn't come with a guarantee of usability sticker. Actually, it comes with an indemnification of liability sticker.

People who are dumb enough to hammer in screws shouldn't be building houses. Whether they do or not isn't exactly my worry.

Don't use the wrong tool for the job and you probably won't get burned.


> The script was 11 lines long (vs 3 lines in Python), it was harder to read and understand.

Note that this might be true for one script, and the opposite might be true for another script. Something is saner in bash, something is better in PS. They have fundamental differences (text- vs. object-based), and neither of them is better than the other in all scenarios. (At least that's my experience.)


I think it's worth noting that powershell is .NET object-based. This means you can interact with powershell objects from a .NET language but not, for example, python. To me this is the fundamental flaw of PS. It's a neat idea as long as you stay within their box, within their ecosystem.

With Bash you get a wealth of tools because everything can handle text.


Googled "powershell ironpython" and got this[0] as first result. Before that, I was going to point out that IronPython, despite it's performance issues and nitpicky differences (there's no 'struct' module, but there's '_struct', which is... struct and they somehow forgot to rename) is still considered a .NET language.

If there's anything wrong with the article (for one thing, it's 4 yo), please point it out. I just brought this up because the IronPython part of .NET is usually forgotten, though still there and has some interesting uses.

[0] http://www.pythondiary.com/blog/Jun.26,2012/ironpython-and-m...


You're missing my point.


Could you please be more explicit about it then?

The part about the .NET objects has already been addressed by others, and I actually like that -- right now at work we're wrestling with a few command line applications that output text (in full UNIX-style) and it's a mess to parse the thing, because it's so badly documented. If we had objects as a result it'd be glorious (not that PS would help, this isn't a bash script we're working with/against).


> Could you please be more explicit about it then?

Sure, it doesn't work with CPython. I shouldn't need to be that explicit though, bring up IronPython is one hell of a nit.


> With Bash you get a wealth of tools because everything can handle text.

... and all those tools work seamlessly in Powershell, too. .NET objects are passed around within Powershell, but traditional dumb text is used for out-of-proc stuff. Where is the "fatal flaw?"

I don't understand where the perceived downside is - you wish Powershell was implemented in Python, not .NET?


> Where is the "fatal flaw?"

The fatal flaw is that I have to distinguish between "within Powershell" and "out-of-proc". I simply don't have this issue with plain text; I don't know or care what language/runtime the programs I use are written in/for because they all use the same interface.


PowerShell objects are actually a superset of . Net objects. They can also represent COM objects, WMI objects, XML nodes, etc. You can also export them to CSV, XML, JSON, and yes, even text. If you have cygwin installed you can pipe to and from the cygwin commands from PowerShell and pipe to and from powershell.exe from your cygwin shell.


Languages are not the same, you'll never have interoperability; try exporting a .NET object with a 64-bit integer to be consumed by JavaScript, for example. Text wins.


PS C:\> 0x1234567812345678

1311768465173141112

PS C:\> 0x1234567812345678 >.\foo.txt ; cat .\foo.txt

1311768465173141112

PS C:\> "WScript.Echo('$(0x1234567812345678)')" >.\foo.js ; cat .\foo.js ; cscript //nologo .\foo.js

WScript.Echo(1311768465173141112)

1.31176846517314E+18

...

I'm not seeing your point.


> I'm not seeing your point.

JavaScript does not have 64-bit integers. So if you exported an object with 64-bit integers to XML, for example, a JavaScript program could not (correctly) deserialize that XML.


Javascript doesn't really have integers, at all, so...


You can have interoperability, COM does it well on Windows. JavaScript, .net, Python, ruby, C, C++ can all access COM methods and attributes.


You would serialise it?

$obj = [PSCustomObject]@{ Number = [long]2 }

$obj | ConvertTo-Json


Try with the number 9223372036854775807. Then try consuming this JSON in Node.


$obj = [PSCustomObject]@{ Number = [string]9223372036854775807 } $obj | ConvertTo-Json

The lack of decent types, is surely a weakness of js?


Yes, but the downside of that is you have to munge the text to do things with it, while with .NET objects you often don't have to do that. And PowerShell certainly does provide facilities for dealing with text, so you can use other languages' tools within PowerShell (and I think with some use of Out-String and similar you could go the other way well enough).


> With Bash you get a wealth of tools because everything can handle text.

I think technically it should be no problem to write some package for most programming languages for interopting with .net objects. In this sense about everything could also handle .net objects.


> With Bash you get a wealth of tools because everything can handle text.

And no autocomplete.


Unix command line autocomplete is fairly good, but it's not useful for discovery of new features or for helping you figure out a CLI without reading anything. It is quite effective at helping a user who knows what they're avoid keystrokes, though.


Bash completion is inferior. It doesn't understand types.


I didn't get this, could you elaborate? Does powershell autocomplete objects it is about to ingest, and before you run the command?


PowerShell v3+ can autocomplete command names, command switches and switch values (if they're a strict set). It can also autocomplete object properties yes.

    $dir = gci
    $dir.<tab> -> $dir.Count


> command names, command switches and switch values (if they're a strict set).

So can bash. How is this different from bash's autocompletion?

> also ... object properties

Well, there aren't objects in bash, so I can't translate this.


Without seeing the script, it's hard to make judgement. Powershell has a ton of alias(Use Get-Alias to find them) and shortcuts, but most people don't use them.


I think most people discourage their use in scripts, which is understandable if you want to maintain the script easily.


I guess the difference between bash scripting and powershell scripting is that you have to learn a lot of things upfront to be productive with Powershell. Bash, on the other hand, with its simpler syntax and collection of text based utilities you can get productive pretty quickly. If you want more power or if you want cleaner code you can always switch to Python et al. Thus, the learning curve is much more gentle. The latter embodies tinkering spirit and self-learning and the former shows its enterprise nature.


The first thing you should learn with PowerShell are the discoverability features: Tab completion, Get-help, get-command, show-command, get-member, get-alias. Last time I checked (and admittedly it's been a few years) bash has man pages and that's it.


I agree with you (was about to post something similar), and wanted to add that some unix commands (which become part of the soul of bash scripts), are sometimes named in weird, unintuitive ways. For one thing, one potentially dangerous command is simply called "dd", and its man page[0] says next to nothing at all about its true power, uses and danger.

[0] http://linux.die.net/man/1/dd


I don't think it's dd itself that's dangerous, rather the fact that it's usage is often paired with root access to raw device nodes on the filesystem.

Even innocuous things like tee, cat, and bash output redirection can mess up your system if you blast something into /dev/sda.


Indeed, without root access you don't get to screw a disk with dd. But let's also admit that saying dd is a tool for copying files is a bit like saying that with a katana sword you can slice pizza... Technically true, but you're likely to get hurt in the process.


Haven't used PS much – only used DuckDuckGo to find what each PS command meant, so it's possible I have misuderstood some, but – these are the bash alternatives, I think:

| :PowerShell | Bash: |

|Tab completion | built-in, OOTB|

|Get-help | `help`|

|get-command | `apropos -s <section> .`|

|show-command | `<command> --help` or `man <command>`|

|get-member | Inapplicable; text has a structure. Use `head -1` to find out, given structure is printed on first line |

|get-alias | `alias`|


What's the bash equivalent of something like this?

Get-Command -Module SQLPS | ?{$_.Parameters.Values.ParameterType -contains [PSCredential]}

In PowerShell, this means "show me all the commands from the SQLPS module that take a credential object as one of the parameters".


This question weighs to powershell's side, and I wouldn't call it fair (and not just because I don't know powershell), but I'll bite.

Print all files in package: `dpkg -L <package name>` (for Debian based OSes)

Filter executable commands: ` | grep 'bin/.'` (assuming the package adheres to standards)

Check parameters of command: `<command> --help` (again, assuming the developers have adhered to convention)

Of course, if one needs to check multiple commands, one will have to use a loop. (Which is basic programming, isn't it?).


But can't you see that's bad?

1. It doesn't work on all distros, and even on Debian you need to already know that "dpkg -L" gets a list of commands. I tried googling "debian distro package tool" and it doesn't tell me about dpkg. Discoverability.

2. The reason you're praying that the package developer put everything in 'bin' is because there's no metadata to distinguish between commands and other files.

3. You're actually executing(!!) the commands to get the help, because, again, no metadata. Parsing the arguments is delegated to the command, so what if the command ignores the --help and reboots your server instead? (Note that if you run a PowerShell cmdlet with -?, it doesn't actually hand control over to the command.)

4. At the end of the day it's not going to work because all of the parameters are strings and all you can look for is the parameter name, which might be "password" or "pass" or "pwd" or anything else the author picked. (Another reason this matters is the PSCredential is stongly-typed and backed by a SecureString, so if the process crashes it won't get leaked into the heap dump. In your Linux command it's just a plain-text string on the heap.)

Now, I'm not trying to say you should give up bash/Linux and become a Windows fan boy. I'm saying you need to take an honest look at bash and decide whether it makes sense to stick with that paradigm in the 21st century.


1. Every distro has its own package tool, and a user (if they're going to be messing with packages) is expected to know them. If a dev/admin can't use `dpkg -L` on Arch Linux, it is their fault for not learning Arch Linux.

I wouldn't expect you to know about dpkg from one Google search, like you wouldn't expect me to know about '?{$_.Parameters.Values.ParameterType' from one Google search, would you?

2. The location of the file IS the metadata! Placing a command outside a bin/ folder in a Debian package is the same as mistyping <whatever metadata lets Get-Command know something is a command>.

3.1. Yeah, sure, executing is bad. So use the manual pages. They are well structured (the structure is parsed every time they are displayed, for example). 3.2 Executing is not that bad, when you trust the source of the commands. It is anti-convention to use arbitrary, non-vetted repos.

4. Looking for a single value is always better than looking for three values, but is the latter really that much more bad? BTW, taking a password as a string argument is wrong in the Linux world too. C'mon, people aren't that stupid. As for where you store it: unless you're handing it over to hardware immediately, there's little protection to it. I did a little bit of searching on what SecureString is (admittedly, not much, maybe you can enlighten me), and is there any reason to believe the encryption key isn't in memory too?

Bash alone isn't what's keeping me on Linux or away from Windows. When bash becomes bad/obsolete/uncool, another will take its place. Or if a new feature seems good/worthwhile/cool, it can get added to bash. The secret (heh) is: open source. Fish happened, zsh happened, and it was easier for them to happen because bash was open source. If they had to reimplement all of bash from scratch, it would have been a little bit discouraging, a little bit too hard, but thankfully it wasn't.

I doubt I'll hardly ever become a fanboy of anything, even Linux, but I'm not going to look at Windows in the same light until the magic of open source has worked on it.


"Which commands from XYZ package require credentials?" hardly seems unfair.

Your suggestion solutions illustrate the point well - you have to memorize some convention of where utils are located, how they display usage info, then cross your fingers and hope developers have followed it. And it's not even complete, since I'm guessing there is no solid convention for parsing a manpage to find which args represent credentials.

In powershell, cmdlets and their args are typed, so you just ask for all cmdlets that have an arg with the credential type. Everything above is tab-completable, too, and thus discoverable at least to some level.


Memorization is a necessity in every endeavour involving a process, even a computer is nothing without some form of memory. Like you remember powershell commands and switches and whatnot, I remember where executables are placed. It may be a convention, but that's only because a restriction hasn't been placed (yay, freedom?); for all practical purposes, it is a rule.

Crossing fingers and hoping devs have followed a rule/convention/sensibility happens everywhere that isn't 100% under one's own control. Like I have to cross my fingers when installing from an .exe or .msi.

> I'm guessing there is no solid convention for parsing a manpage to ... You guess wrong. (There is no convention for parsing a manpage, only for writing one, but isn't that enough?)

> Everything above is tab-completable So it is in the *nix world. Check out oh-my-zsh (if bash's tab-completion wasn't enough for you), it has an option to enable a ridiculous (and annoying, IMO) amount of tab-completion.


I made a big push at some point to start using Powershell instead of the horrible .bat files I had written at some point (and their arcane unreadable commands). But Powershell's syntax, convoluted names and the unreadable code we had to write to do simple things really made me reconsider seriously. I simply use Python for these things (99% time it has all I need).


I don't really understand this. If you don't like the verbose names of PowerShell commands, you still have the option to set up command aliases. Out of the box, PowerShell includes a number of common Unix terminal commands as aliases:

https://technet.microsoft.com/en-us/library/dd347739.aspx


Well right there, that's an extra step that I don't need to do when using Python. But I'll have a look at the link, thanks!


Ha, that explains why the other day I typed 'ls' out of habit in Powershell and it still printed out the folder contents. Now that I know it's not just that one command, it should make some things easier.


One thing is that Powershell has some built-in "cmdlets" which would be buried in the filesystem (and not in the PATH) otherwise. I'm thinking specifically about the PS equivalent of signtool.exe, which is normally in an SDK path under program files (x86) depending on which SDK(s) you have installed.

Do I remember the name of the signing cmdlet(s)? Nope! Is this really better than just using alias, or changing the PATH? Probably not.

Another reason is vendor support. For example, VMware publishes a set of PS cmdlets as 'PowerCLI' for doing stuff in vSphere, but if you want to do something outside PS you're going to have to script/code against an SDK. I suspect there are other vendors doing the same thing. That may be a PS benefit. I usually end up writing a script instead although I found e.g. bulk movement of VMs from one set of datastores to another easier in PS.

The final thing I can think of is that there are a few situations where maybe you want things to stay in-process, and you get that w/ PS whereas you wouldn't with bash. An example I have is a script that facilitates remote deployment of an MSI with impersonation of a user on the remote machine. This is pretty straightforward with a WMIObject in PS, but not in cygwin bash since Windows doesn't really have sudo or su -c (runas only works interactively) and wmic doesn't offer any impersonation capability.

None of the above are really compelling for me, I end up spending 99+% of my time in bash/tmux/mintty.


> I can't see what benefit PS has over cygwin bash but I'd love to hear ideas

For Exchange server administration, it is very useful.

Enter-PSSession give you a remote shell. There was news a while back that Microsoft was going to port OpenSSH to Windows, so things will improve.

I still prefer a Unix environment; tools like find are just a must-have. But compared to cmd.exe, which is the baseline many Windows people look at, it is a huge improvement.

For serious scripting, I prefer Perl, though.


This will help with longwinded'ness

gal * | more

A whole list of short alias's


>> Let's be honest. What many people think of as "the default Windows command line", cmd.exe, is atrociously bad. Selection is awkward, resizing is hard, the syntax is arcane, the list goes on. If you do nothing else, there are two things you can do to make the basic, vanilla experience bearable.

Funny, from a guy coming from Windows to Unix I think the exact opposite. Each command comes with a bazillion options and the defaults are simply atrocious (to read the man, oy). Yes I understand that you can tailor each command in some startup script but why? It almost feels like every command needs to be created to solve 5 million things when 99% of the time you use it for 1 or 2 things. A few of my favorites:

Scripting:

A = 123 vs A= 123 vs A=123 should be the same!

Please use trim() in your program when parsing tokens!

Keyboard:

Please, for the love of god, make the keyboard behave like a keyboard. I don't want to be logged into some terminal and have the Backspace not behave like a backspace (^H??). Yes, I'm sure I can make it work via some, again, configuration magic or enter emacs mode, but, again, why?

cd.. should just work.

</rant>

Having been on unix for the last 7mo after years of windows, I do like some things but let's not be too quick to call the kettle black.


> I don't want to be logged into some terminal and have the Backspace not behave like a backspace (^H??). Yes, I'm sure I can make it work via some, again, configuration magic or enter emacs mode, but, again, why?

You don't have to do any magic for that normally. Even if using just xterm with bash, backspace should behave like backspace almost everywhere. You had some weird configuration there – possible you used the terminal of a greybeard?


I think you're correct on this one. I ran into this issue once and it was some silly, easily fixed issue. Sadly I don't remember what it was.


I remember a while ago, being a kid, visiting some relatives, when I've asked my guest elders why our host relatives have so many ignored problems scattered around. They discretely told me that our hosts got used to and that don't notice those anymore. This is how our mind works. In order to get out of problem blindness one may have to cure her senses or the said problems have to grow past the bearable levels. You have the gift of having clean senses, for now.


This is the Android vs Apple paradigm. Customization available to a fault vs "appliance" that just plain works...

Each has their strengths and pain points. There's a reason normal people use Windows and Power Users gravitate to Linux.


I'm a power user and I work in Windows(+Python). I absolutely hate compatibility issues on stupid stuff that plague almost every Linux distro. And when there aren't (oh the rare few cases), then you have to compile half the libraries in the system again (take the hint, Debian!). The only distro that was bearable was Mint, and then we got the poisoned ISOs.

So, Windows+Python it is. If you really miss the command line utils, theres the GNU Core Utils package to solve your life (though pipes still behave slightly different and that may show in a contrived command).


Are you on Solaris? ^H is ancient history and not a thing on Linux.


About the ^H, are you by any means telneting into a network server? That's the only way to get this problem that I know of on a modern Linux.

If so, use nc or ncat, telnet expects a terminal at the other end, something no system exports anymore. It's only there for interaction with ancient configurations.


> Having been on unix for the last 7mo after years of windows, I do like some things but let's not be too quick to call the kettle black

Who's calling the kettle black? You seem to be painting this as a Windows vs. Unix thing, but the original article never mentioned Unix.


let me guess (the keyboard is the give away) when you say unix, you mean osx. Yeah, that terminal induces rage, and the bash is like 40 years stale.


> A= 123

> cd..

So your rant is about the syntax, of a language established for decades. You have options though: modify bash, or raise awareness enough that a simple `alias cd..='cd ..'` is included in the default release.


At our office we jokingly refer to powershell as "two googles per line" - a term coined by its strongest proponent at the company.

It thought it would come naturally over time, but it never does. It seems needlessly cryptic and verbose in so many ways. I've started using LinqPad for stuff I would normally do in cmd now.


Learning Bash is just as cryptic. At least powershell function names have logic behind them.


I've only been working professionally with linux for 5-ish years, but i'd say that i'm still at the "2 googles per command" number for bash.

Some of it stems from the fact that i just don't use it enough, but most of it from the fact that this shit just isn't intuitive. why is -b the flag for key length in ssh-keygen? Why is -v the flag for "don't include" in grep? I have those memorized now, but there is no way they are "intuitive".


> why is -b the flag for key length in ssh-keygen?

Because the length is given in "bits". I get your point, but that's a terrible example! :-)


Now that you've said that, i'll never forget it again (although what the hell does -t stand for then?)

But the point is that even though it's most likely "my fault" for not reading the manual correctly (i'm not saying you were implying that, but often i do feel that it's ultimately because of my laziness that i have these problems), they aren't "intuitive" in the sense that that you can just pick it up and go.

The one thing my "dream linux" system would borrow from powershell is the tab-completion for flags and sub-commands.

If i could type `git ` and hit tab and see a list of what is possible (with a quick one-sentence explanation of that sub-command) it would completely turn my experience around.

But even that takes "domain knowledge" that tab auto-completes... This stuff is hard!


> Now that you've said that, i'll never forget it again (although what the hell does -t stand for then?)

The "type" of key. :D

It would be nice to have a more fully featured auto-complete and it is feasible to do. I'd hope that it's the kind of thing that gnu-utils could get a standard for that other tools could just provide a completion script, rather than each shell having to do its own. Maybe someone's already working on it.


>The one thing my "dream linux" system would borrow from powershell is the tab-completion for flags and sub-commands

You might want to check out some alternative shells: The fish shell does this out of the box, it's really nice. For something more bash-like, I think zsh can too (but you might have to set it up in a config file)


>>Why is -v the flag for "don't include" in grep?

As user yread said, it's for inVert (the sense of the pattern match, from "matches" to "does not match"). You're right, it is non-intuitive.

One of the issues is that when you use single letter options, a particular letter could potentially stand more than one expanded word, e.g. in the case of v, it is more commonly used for Verbose or Version. Even there, it varies. Some commands use -v for version, others use -V (e.g. python does), and some use --version.

GNU's long option format is a partial solution to that, but involves more typing. E.g. --verbose or --version or --invert. Also the command lines get longer then. No perfect solution as of now.

You're right, over the years, with more and more people creating commands, and with no well-defined standard in the earlier years at least, the whole scene of command line tool names and options has become something of a mess. Later one some sort of standards and conventions have been created or evolved, informally, but not many command creators necessarily follow them.

http://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_...

Also, they are pretty detailed, so it is somewhat time-consuming and complex to implement those guidelines in full.


-n for negative or negate or not-in probably would have been more intuitive, but yes fundamnetally 1-character parameters is a bit limited.


> Some of it stems from the fact that i just don't use it enough, but most of it from the fact that this shit just isn't intuitive.

I have exactly the same problem.

I use Linux since about 8 years but somehow I just don't use the commandline very often so I forget stuff all the time. Because of this I have half a dozen post-its glued to my monitor for all the grep/git/whatever tricks I just can't keep in my head. And for other stuff I use about once a year I have a long linux_tricks.txt on my desktop where I write down all the tricky and obscure command line stuff.


If you're interested in getting past this stage of learning the Linux/Bash environment, I'd recommend reading man pages.

I worked with someone who introduced me to this approach, and at first I was like "I'll just Google it again and get on with my life," but once I forced my way through a couple of them it's really opened my eyes and changed the way I use the tools available.

ls has enough options to spell most people's names (capitalization included), and a lot of grep pipelines can be replaced with options passed to grep. It turns out that we're almost always doing things the hard way or reinventing the wheel.


Thx for the tip about man pages, somehow I never thought about reading them.


Holy shit git!

I need to reset my git repo to match origin, is it git reset hard --HEAD or git reset HEAD --hard?

I'm like 90% sure they switch it with every update.


It's just git reset --hard. HEAD is implied.

Edit: To be more specific:

    git  # the executable
    reset  # the operation
    --hard # the type of reset being done (hard reset)
    HEAD  # where to reset *to*. Defaults to HEAD if not specified.


You can just leave out HEAD since it is implied, but understanding a little bit about git, like what the head is supposed to be, would probably help you.


For rare commands that are repeated every so often history search comes in handy.


yeah I also always have to google the -v and them I'm like ahaaa it's inVert! And next time I have to google it again


I don't see anything illogical in fg bg ls cd mkdir cp rm man ... Perhaps a little cryptic, but it's just mnemonics. Not to mention that short names are very convenient in a text-based shell.


Point. I'm developer, not ops. I'm comparing PowerShell to true programming languages, not to Bash.


Agree on that one, it's really verbose and ugly. I liked the idea of a cmd that integrates so nicely with .NET but I don't think it worked out this time.

We use powershell a lot at work for developer setup stuff and other common tasks we do on a daily basis and at this point I've considered just writing my own language to do it or find something else.


Why don't you just use Python, Ruby or even C#? Why write your own language?

I wanted to learn Ruby a while back but didn't have a web project to work on so I started writing a load of scripts in Ruby instead. It worked out fine.


C# has the same issue really, although we do it use for some other tooling and whatnot as we're a .NET shop.

Don't know much Ruby or Python to be honest so I'm not sure how could I apply them but I'll dig around sometime soon.


I don't really understand this- I always found the "get-help" commandlet to be sufficiently informative, unless they were using parts of the .NET framework that I wasn't already familiar with, in which case I needed to go read about those objects/etc. on my own. Is this that bad?


Well, the man page of nearly any command is also good enough to avoid a google search (yes, git is an exception).

That isn't much comforting. And frankly, MS always pushed Power Shell as a better way to do things than the ancient options for command line, thus color me disappointed that it couldn't be better than the "default choice" Bash.


I guess it won't help if you don't know what cmdlet you want to use.


I think a lot of the hate on powershell is that it chooses to do things very similar to existing languages, but just different enough to confuse practitioners of anything else.

Posh also suffers in its somewhat easy to invoke any .NET library, so people start comparing it to a more tooled programming language or something with more sane libraries, and the "ISE" is nowhere close to an IDE (why isnt powershell a first class citizen in visual studio! yes I know there are tools, they are not great.)

Nonetheless, after a few years of working in sql server I have adopted more and more posh in my life because its simply the fastest way to get things done if you are doing windows server management.

I usually find myself on one of these two places if I am looking for something:

Mike Fal (SQL Server focus, he is great) http://www.mikefal.net/

Hey Scripting Guy! https://blogs.technet.microsoft.com/heyscriptingguy/

edit: forgot to mention that MSFT helped to cause problems by massive changing how the language did things over time(usually for the better), so ps1 vs ps4 is crazy different, another reason to be annoyed because which version comes with which product is a fun skew to deal with (thanks sqlps having ps2.0!)


I don't really care about "It's Just Text" vs "Data Typing FTW." There are different tradeoffs at play here, and to my mind that's ok. I'm just thrilled to have something that's: - Internally consistent - Well documented - Available by default - Full featured - Still being improved

Sure, I'm not thrilled with having to learn another language to get anything done. But it's so much better than what came before that I don't care. Besides, Bash and friends certainly have their quirks as well.


I tried both ConEmu (twice) and Console2 in the past, but both were too unstable for regular use. If someone can convince me that the situation has markedly improved, I might try again, but I guess I'll just wait until we upgrade to Windows 10 at my workplace (which they say is any day now).


ConEmu does seem to have gotten a lot more stable in the last few months


I'll confirm this. During a previous project, it would sometimes crash, or history would get wonky, but I've not seen any of those behaviors while working on my current project. I generally am just using the terminal to run tasks, so I'm not sure I qualify as a "power user."


I use ConEmu daily. I wouldn't call myself a power user (e.g. I never have more than five tabs open at once), but I do use it regularly for a number of tasks.

In the past, say, six months, I cannot remember having any trouble with it.


I'm using ConsoleZ now. It's the successor of Console2; I have had no problems with stability.


I use ConEmu (actually cmder - ConEmu with some out-of-box enhancements) every day at work under Windows 7 Pro. Absolutely no issues to report.


Happy ConEmu plus clink user for at least a year, I suspect more, but I don't keep track, I just move on.


Hmm, just installed clink 0.4.7 (with autorun disabled for now). "clink autorun --help" consistently crashes. But at least it hasn't taken down the console yet, so I guess I'll try it out for some time. It's really a nice concept.


mmmrrrm, don't know, don't remember. I do know that when I start ConEmu, I have to ctrl-alt-J to get command line features. So maybe I had trouble with autorun too? Don't remember.


  > clink autorun --help
  Clink v0.4.4 [git:a60c0a] Copyright (c) 2014 Martin Ridgers
  http://mridgers.github.io/clink
  
    -i, --install         Installs an autorun entry for cmd.exe.
    -u, --uninstall       Uninstalls an autorun entry.
    -s, --show            Displays the current autorun settings.
    -v, --value <string>  Sets the autorun to <string>.
    -h, --help            Shows this help text.
    -- <args>             Pass <args> that follow '--' on to Clink.

  >clink autorun --show
  native : "C:\Program Files (x86)\clink\0.4.4\clink" inject --profile "~\clink"
   wow64 : "C:\Program Files (x86)\clink\0.4.4\clink" inject --profile "~\clink"


I've tried one or both earlier. Didn't quite get what the difference is. (Maybe did not check well enough at the time.) Are they related tools, or is one a substitute for the other?


https://mridgers.github.io/clink/

"Clink combines the native Windows shell cmd.exe with the powerful command line editing features of the GNU Readline library, which provides rich completion, history, and line-editing capabilities. Readline is best known for its use in the well-known Unix shell Bash, the standard shell for Mac OS X and many Linux distributions."

https://conemu.github.io/

"ConEmu-Maximus5 is a Windows console emulator with tabs, which presents multiple consoles and simple GUI applications as one customizable GUI window with various features."


I have been using ConEmu since December and I am yet to run in issue. I use it with Gow and clink.

What issues did you face?


Crashes of the console, usually happening after executing a few commands. This was a few years ago, probably on WinXP, but could be Win7 (I'm on Win8.1 now).


I've been using ConEmu for a while and have had no issues with it as far as I can remember.


No mention of clink ? surprising, cmd.exe meets readline. Highest ROI 'update' I know on Windows https://mridgers.github.io/clink/


ConEmu plus clink is my mitigation of choice.

Line oriented copy/paste, instead of cell oriented, is a big win.


In Win10 there is finally line-based copy/paste built-in. You can still get block-based by holding Alt.


Most of my issues with windows command line have been solved by installing the unix tools to the path when installing git. Provides most of the commands I need (including a native ssh that works from the windows+r dialouge) and I have mingw if I need to do something with bash itself.

This on windows 10 with it's nice new command window is pretty nice, but I still do anything serious on my macbook.


> "And, purely subjectively, I think the .ps1 syntax is a lot more readable than the old .bat syntax."

The Author does say "subjectively" but in my experience, both personally and with others, the reverse is true. Powershell can seem to be really cryptic.


Bash can be _extremely_ cryptic as well, we just learned it over time. Look at awk :)


Why use bash when you can use Python with os and sys modules?


I prefer Python when appropriate, but if you're going to "shell out" a lot and pipe a bunch of commands together it starts getting too verbose and loses it's elegance. I agree with other posters that bash is not intuitive, but if you've worked with it for a long time, there's nothing like being able to cat | grep | sed in a one-liner, rather than creating a bunch of Process objects, etc.


If you're doing cat, grep, sed I'd say that bash is very intuitive and I use it for that purpose all the time. If you're writing bash scripts, with if structures and loops and everything, then just python.


Perhaps an unpopular opinion, but I still prefer to stay in bash even when I need loops and conditionals. If I'm already writing in Python, then sure, Python it is. Or ruby, or js, or whatever I'm in. But when I'm in bash and I can do it easily enough in bash, why complicate?


Python is great for writing scripts, but not so great for doing interactive maintenance.


then perl, then python, then bash.


Then back at awk.


Heh, I didn't want to mention it. awk strive from word of mouth.


I guess it's heretical to say this in some circles but I really like PowerShell, despite its faults. An object-oriented shell is a really good idea that saves a lot of time trying to munge texts with regular expressions and such.

That said the return semantics stink.


Git for Windows is bundled with Git-Bash. A very Linux-like commande line. Works like a charm.

I also use MobaXTerm as my Putty replacement. It also comes with a Bash terminal that works fine. Very handy!

(Two reasons why I love to have learnt Bash)


Git for Windows is probably the first thing I install as soon as I log into a new Windows computer.

Granted, bash may not be the most intuitive shell ever, but it just works about everywhere and this is a huge advantage when switching OS regularly.


> One of the reasons you use Windows is so you don't have to use the command line.

It's the other way around: One of the reasons I don't use Windows is because I have to use the command line.


I develop on Windows and use cmd.exe daily (for simpler tasks like running Gulp or PhantomJS). It's hard to overstate how much of an improvement Windows 10 brings to the command line. Keyboard cut and paste, resizing, better text selection seem so wonderful. It's a crime it took Microsoft this long for these simple features.

There's also other handy improvements, like typing "cmd" into the file explorer location bar to open a command window to the current location you are viewing.


Yes! I joined Microsoft 2 years ago, prior to that was on OS X. I couldn't believe how awful cmd.exe was. It was like if a college student half implemented some homework assignment and we all had to use it. I tried using cygwin, PowerShell, and other shells but that was hard because too much of my day to day work depended on shared scripts that I would have to manually update for my shell. So I was stuck with cmd.exe and it was miserable.

Windows 10 fixed that with the improvements you mentioned. It's still no "Terminal", but it's now about 80% as good, instead of 1%.


One of the reasons you use Windows is so you don't have to use the command line. But sometimes it's unavoidable—maybe you need to do some advanced git-wrangling, or you're developing in an environment with CLI-based tools that are far more mature than their GUI counterparts.

This viewpoint is just plain wrong. Since GUIs typically don't have a way of doing sequences of commands other than clicking and waiting, then clicking again, or of automatically making decisions, the biggest reason to use a CLI would be to express things that you can't with a GUI - like anything that requires a flow-of-control with if-then-else.

After all, that's one of the reasons that rebuses are fun - they're indeterminate and it's fun to de-ambiguate them. It's less fun to have to do all de-ambiguation yourself, when a simple pipeline or while-loop would do the trick.


I think Powershell is a huge leap beyond Command. I just wish scripting was easier with it, speaking of its return values: http://stackoverflow.com/a/10288256/9744

Maybe there are better programming patterns for me to use here. Coming from traditional imperative languages, I was confused though, especially when I got to nests of functions, return values, and debug outputs. I mean, I later understood why things worked like they did -- I just had a hard time wrapping my code around the philosophy. Which is unusual for me to have with a language from Microsoft in their post-.NET era.


> I know what you're probably thinking. One of the reasons you use Windows is so you don't have to use the command line.

I know what I'm thinking. One of the reasons I don't use Windows is that its command line is a second or third class citizen.


Right. I don't understand how people get any real work done on a Windows machine.

What should take 2 seconds to type takes 20 seconds to find in godawful menus, that get harder and harder to find with each new version of Windows.


I did Windows dev exclusively for a long time, and was an early Powershell adopter. Recently I switched companies and now I swap back and forth from Win10 (PS v5) to OSX (Terminal). I'm massively more productive in Powershell, mostly due to my inexperience with Unix. There are a few things I think I can legitimately argue, though:

The power of the unix command line is mostly from the utility commands themselves, not from the shell language/ecosystem. Nobody seems to be super enthusiastic about bash as a language (see all of the "at this point I just go to perl/python/etc" comments), but the commands themselves are super powerful and flexible. If you put in the time to really learn the commands and their flags, you can do quite a lot. Watching experienced unix users at the prompt, I routinely think "oh nice, that's a great command to have", but rarely "oh that's a handy language feature" or "wow Bash made that really easy".

With Powershell, it's kind of the opposite IMO. The language and ecosystem are mostly well-thought-out, consistent, and powerful. Everything-is-typed, pervasive and awesome tab-completion, mature pipeline system, decoupling of data and how it's displayed, access to the .NET standard libs, ease of extensibility and scripting (oh god it's so nice never neededing to parse arguments!), reflective help system and discoverability features, easily hostable in other apps... That all comes from the ecosystem. Where Powershell often falls flat is the limited set of built-in commands, or the lack of sensible flags/options for those commands which do exist. You're often falling back to legacy cmd.exe-era executable utils, or invoking some .NET API, both of which result in more verbose, awkward code. e.g. reading/writing the registry is SUCH A PAIN with powershell builtins (why?!?!?), so reg.exe it is. Much of that comes from Powershell's relative youth (the set of builtins and their flags is still evolving), and the relative script-unfriendliness of Windows as an OS compared to unix.

So for a particular action, in unix you have have a utility (or even N utilities) with 15 arguments to handle 95% of possible cases, in Powershell you'll get a cmdlet with maybe 5 or 6 arguments that handles 75% of cases, but the output is an object so the remaining 25% can be done by calling some method or grabbing a field. Both approaches have their strengths and drawbacks. The Powershell approach tends to scale better, I'd say - you can create fairly large scripts/packages in pure Powershell without needing to bail out to Python or C#.


>Upgrade to Windows 10... the benefits really can't be overstated.

except that there's tons of drawbacks to counteract said benefits. Privacy notwithstanding, power-use has been fractured and the flow of configuration ruined in 10


I've been wanting bash style completion in a Windows Command Line for so long. Big thanks to the author for the PSReadLine tip; it works perfectly in ConEmu whereas Clink wouldn't work at all.


http://scoop.sh/ has been a nice-to-have tool, similar to homebrew on osx


anybody tried cash [0] ?

[0] https://github.com/dthree/cash


I didn't expect there were a lot of people who knew well about PowerShell here. I like PowerShell.


I don't use Windows anymore so I don't care much. But, When does Windows offer a terminal emulator with sane character encoding(UTF-8)?

This is 2016, CP932(Shift JIS with IBM extension) shall be abandoned.


Windows is no go for me as long as there will be no option to use ansible from cmd - fortunately you can manage windows box from OSX or Linux box with ansible


Why would you even want to make Windows command line better, instead of using a state of the art command line of Linux via a VM running in Windows, if you really cannot escape the Windows realm ?


Because a VM is overkill and won't allow you to interact with the Windows host.


Windows used to provide Interix which was a subsystem that allowed use to use quite a bunch of posix utilities and offered quite a very good integration with Windows. You could do quite a lot of things with it (we used it to convert a unix app to windows in record time) and it was IMO superior to Cygwin.

But that was 10 years ago, it disappeared at some point, being integrated somewhere in either the server version or the professional edition (named something like Unix Service for Windows) I lost track.

Considering all the work that MS is putting in interoperability those days, I'm wondering if it will not make a come back at some point.


Good luck with file permissions on the Windows host. You are in for a fun time.


Because not everyone shares your opinions. I'm not a fan of Powershell, but one thing I love about the design is that it works on objects, not text. UNIX philosphy relies heavily on text and it keeps some things simple, but when you need to move beyond that to more complex structure, the UNIX command-line starts breaking down, whereas Powershell pipes, etc. continue to do well. There are good ideas out there beyond "just use Linux."


If the Linux command line is state of the art, then the art hasn't advanced that far. Too much of it is frozen in time, with constraints from PDP-11s with two-tone 80-char displays, and insane, arcane UI that made sense to the wizards of that day, but less so to we mere mortals. Lots of inertia there.

Still CMD is worse, and Powershell is different, but maybe not any better...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: