Hacker News new | ask | show | jobs
by voltagex_ 4259 days ago
I'm not sure I agree with the "no JSON, please" remark. If I'm parsing normal *nix output I'm going to have to use sed, grep, awk, cut or whatever and the invocation is probably going to be different for each tool.

If it's JSON and I know what object I want, I just have to pipe to something like jq [1].

PowerShell takes this further and uses the concept of passing objects around - so I can do things like ls | $_.Name and extract a list of file names (or paths, or extensions etc)

[1]: http://stedolan.github.io/jq/

5 comments

+1 for jq. A lot of my work these days involves using web APIs in addition to "local" ones from CLI tools. xpath was good for dealing with XML stuff in a similar fashion, and HTML-XML-utils is an awesome suite of CLI things for slicing and dicing, if you're into that sort of thing: http://www.maketecheasier.com/manipulate-html-and-xml-files-...
xmlstarlet is also handy for command-line XML parsing:

http://xmlstar.sourceforge.net/

Agree, had to use it extensively several years ago, it saved me so much time. But even then the development seemed to have stopped on this tool.
I was also constantly thinking of PowerShell while reading that. A PowerShell-specific list of such advice would actually be rather short, given that most of the pitfalls are already avoided. I still firmly believe that PowerShell is actually a much more consistent Unix shell in that several concepts that ought to be separate are actually orthogonal. Let's see:

Input from stdin, output to stdout: Nicely side-stepped in that most cmdlets allow binding pipeline input to a parameter (either byval or byname, if needed). Filters are trivial to write, though.

Output should be free from headers: Side-stepped as well, in that decoration comes from the Format-* cmdlets that should only ever be at the end of a pipeline that's shown to the user.

Simple to parse and to compose: Well, objects. Can't beat parsing that you don't need to do.

Output as API: Well, since output is either a collection of objects or nothing (e.g. if an exception happened) there isn't the problem that you're getting back something unexpected.

Diagnostics on stderr: Automatic with exceptions and Write-Error. As an added bonus, warnings are on stream 2, debug output on stream 3 and verbose output on stream 4. All nicely separable if needed.

Signal failures with an exit status. Automatic if needed ($?), but usually exception handling is easier.

Portable output: That's about the only advice that would still hold and be valuable. E.g. Select-String returns objects with a Filename property which is not a FileInfo, but only a string; subject to the same restrictions that are mentioned in the article.

Omit needless dagnostics: Since those would be either on the debug or verbose stream they can be silenced easily, don't interfere with other things you care about and cmdlets have a switch for either of that, which means you only get that stuff if you actually care about it.

Avoid interactivity: Can happen when using the shell interactively, e.g.

    Home:> Remove-Item

    cmdlet Remove-Item at command pipeline position 1
    Supply values for the following parameters:
    Path[0]: _
However, this only ever happens if you do not bind anything to a parameter, which shouldn't happen in scripts. If you bind $null to a parameter, e.g. because pipeline input is empty or a subexpression returned no result, then an error is thrown instead, avoiding this problem.

Nitpick: You'd need ls | % Name or ls | % { $_.Name } there. Otherwise you'd have an expression as a pipeline element, which isn't allowed.

I have never used a computer that had access to Powershell, but in my new job I may have to do some small stuff to tie some systems together. I'm terrified of learning it because I don't want to be lured into some kind of lock-in scenario.
Well, you can only use it on Windows. But I mean come on, "terrified?" Bash scripts are not too useful in Windows either.
Spending a lot of time learning non-portable technologies isn't a decision to be taken lightly.
Well, if it's part of your job I'd say it's not a decision at all...
If you can't accomplish the same goals in a portable way. Of course, if you can put the knowledge to work as soon as you learn it, you're already starting to recoup your investment.
cygwin does it's job well.
cygwin works fine but if your task is, for instance, to configure Windows machines, it's not very useful.
My issue with Powershell is it creates a distance from the scripting language and an ordinary executable, which makes it difficult to use just a little bit (and I suppose violates the rule about composability).
On Mac (OS NeXT, perhaps?), the convention seems to be that most commands produce human readable output by default, but you can pass a parameter like -x or -xml to get (usually) XML, machine-readable output, and with some tools, -j or -json will give you that format.

But then you've oddities like plutil behaving like gzip by modifying the file you specify rather than printing to stdout. You have to pass -o and a dash to get it to leave the file alone and instead reformat it to stdout. That one gets me every time. And I'm not alone: https://twitter.com/mavcunha/status/417823730505895936

But other parts are nice. For instance, "system_profiler -xml > MyReport.spx" generates XML that will open in the System Profiler GUI app. The XML generated is usually a Plist, since that's as native to the platform as the Registry might be to Windows...

Let me know when PowerShell gets tabs though. Maybe there's a Terminal.app port running in Mono somewhere? Seriously, I wish somebody would build a better terminal, maybe get creative with scrollback and chaining commands, and ship it in an OS... with tabs. ;-)

Not sure if its what you had in mind for Windows and tabs but I've found ConsoleZ [1] quite nice and allows powershell, cmd and others to have tabs.

[1] https://github.com/cbucher/console

Yeah, I know it's possible with adding, I've tried Console2 and ConEmu before. But I'd like it to just work out of the box with no extra software, as it does on Mac or Linux. Until Windows 10, that terminal hadn't changed since NT days...
You can use the PowerShell ISE. Which has tabs and you can just hide the script pane to get only the console itself. Startup time is a bit hefty, but if you have tabs you probably create new tabs way more often than the tab container.

Especially for PowerShell the whole problem that Console2, etc. have is trivial, as you have an API to create a host application instead of relying on polling a hidden console window. The console host is just one of those hosts.

I'm drawing a blank on the specifics but some things will work in the PowerShell prompt that won't work in the ISE.
Programs that want access to the actual console. E.g. for interactive input, moving the cursor around, etc.
I've been digging conemu[1]

[1]: https://code.google.com/p/conemu-maximus5/

Yeah, I love jq. With a tool like that, I'd actually like to have an option for standard *nix tools to output JSON. Dealing with structured output would be far easier than counting which columns need to be extracted, using sed to split things, etc.
jq looks nice, I use another similar tool quite a lot [1].

[1]: https://github.com/trentm/json