Follow Slashdot blog updates by subscribing to our blog RSS feed

 



Forgot your password?
typodupeerror
×
Programming

Journal SL Baur's Journal: The clash of two cultures

In the recent History of the Bourne Shell article link here I got into an exchange with a PowerSheller (likely a developer). Due to the length and thoughtfulness of his defense of PowerShell seen below my comment here - link here I'm journaling it.

Thank you for a thoughtful response. I don't agree with you, but at
lease I now know where you're coming from. So on that basis ...

How about these:
Pipes are object-oriented. Commands are piping objects instead of plainly text. This means that

If you know who I am, you'll know that I do not consider "object oriented" to be a feature. I also regard writings such as TFman pages perltoot and perltooc as "dick waving".[1]

The advantage of using plaintext as a default is that it is highly resilent to underlying architectural differences. Throughout my career I've always been in an environment where I have had to interact with hosts with different OSes and different CPU types. Therefore, in my mind, something like `foo | ssh remotehost somecommand | bar' should Just Work. It shouldn't matter whether `remotehost' is 32 or 64 bit, or running HP/UX or Solaris or Linux. Nor should it matter what version of the O/S is being used.

Once you have to take that sort of stuff into account, you're looking at something like ASN.1 to represent data in a pipeline.

subsequent commands can refer to properties instead of parsing columns trying to get delimiters right and avoid false positives

Agreed that this is a "limitation" in a dead simple plaintext type approach.

tools/commands do not have to worry that columns may not be wide enough

Heh. No comment.[2]

you don't have to suppress headers and formatting information and

Well, actually you *do* want to do that, on data that's going to be post-processed by an arbitrary number of other programs.

values are passed strongly typed, i.e. dates are just dates and you need not worry about ISO formats to sort correctly

That requires specialized (and localized) knowledge built into the shell.

text (string) is just an object type so you can still just pipe text if you so choose.

Whew.

instead of passive text the script/commands may interact with the objects. As an example, ProcessInfo objects (returned from the ps cmdlet) expose a WaitForExit method which allows scripts to wait for a process to terminate without resorting to ps loop polling or specialized tools.

See above comment about stuff crammed into the shell. Also, that's what the `wait' builtin is for.

First class strongly typed script language is embedded. It understands floats, objects, dates, times etc. Unlike when you drop into Perl or Python, PowerShell script still allows the use of commands with full piping embedded in scripts.

I'm not sure what point you're trying to make. Perl *does* have embedded capabilities to use shell syntax and semantics in pipelines and I would be surprised if Python did not have something similar.

Provider/drive architecture which is extensible. PowerShell comes with providers for file system, registry, credentials store, certificate store, environment, variables, functions and aliases. Providers are user-extensible and providers also exist for Active Directory/LDAP, Exchange etc. The upshot: You can manipulate
any store just like you manipulate directories and files, using the exact same commands. You can change "current location" into Active Directory, go to an organizational unit and start adding/removing members like it were files. With the exact same commands.

Once upon a time, one could simply use cat(1) as a mail reader and password file reader.

I am positive that the retro changes that MSExchange have wrought on the world are not for a positive benefit. I am dubious about Active Directory as well.

structured, nestable exception handling using try-catch-finally blocks.

Modern Unix shells give you access to similar capabilities, sans `nestable'.

transaction support (v2). Lets you rollback/commit changes to file system, registry or any other transaction aware provider as atomic transactions. Yes, NTFS is transactional.

It doesn't solve the problem of doing transactional scripting with transaction-unaware applications that need to be transaction-aware. CF my earliest XEmacs release building scripts.

script signing. By default PS will not let you run any script files unless they have been signed by a trusted authority, which can be yourself, your IT dept. or a 3rd party supplier. This can be set to only block unsigned scripts received from the internet/mail or never block (stupid).

I wouldn't consider this a feature, but that's a personal opinion.

debugger support (v2). Not just tracing but actual debugging with breakpoints, variable inspections/changes/continue etc.

Such facilities can be built into scripts. Tracing is provided with the `-x' option, which can also be set within a script.

Culture and internationalization support. Allows localized scripts with messages from multiple language dictionaries.

I'm not aware of anyone doing this with the Unix shell (and if someone is, please enlighten me).

But you wanted to see something that could not be done more easily in a modern nix shell (like bash or zsh?). Let's see:

# list all empty directories below current:
ls . -r | ?{!($_|ls)}

for i in $(find . -type d); do
[ $(ls -a $i 2>/dev/null| wc -l) -eq 2 ] && echo $i
done

This should work the same as in Version 7 Unix.

# list all directories below current which are empty except for
*.tmp files:
ls . -r | ?{!($_|ls -ex *.tmp)}

for i in $(find . -type d); do
[ $(echo $i/*.tmp 2>/dev/null) != "$i/*.tmp" ] && echo $i
done

# a better slashdot rss reader
$wc=new-object Net.WebClient
$rss=[xml]$wc.DownloadString("http://rss.slashdot.org/Slashdot/slashdot")
$rss.RDF.item | ?{$_.creator -ne "kdawson"} | fl
title,description

Muwahaha. There's no way I can possibly improve on that one.

# or just read the slashdot headlines through the speakers
$wc=new-object Net.WebClient
$rss=[xml]$wc.DownloadString("http://rss.slashdot.org/Slashdot/slashdot")
$voice=new-object -com SAPI.SPVoice
$rss.RDF.item | %{[void]$voice.speak($_.title)}

Does this also work on GNOME, KDE and MacOS X?

# list threads consuming more than 100MB (working set)
ps | ?{$_.WS -gt 100MB}

Variant ps(1) output is a known portability issue. Does this script
work the same when PowerShell is running under Unix?

# which 10 processes has been using most CPU?
ps | sort -desc CPU | select -first 10

$ ps -ax -O '%cpu' | sort -rnk 2 | head -10

# but how is their average CPU utilization since start?
#(format in a table with process name and average CPU utilization in percent with 2 decimals)
$big = ps | sort -desc CPU | select -first 10
$big | ft Name, @{ E={$_.CPU/((get-date)-$_.StartTime).TotalSeconds};
L="CPU avg"; F="{0:p2}"}

That one I'd have to resort to a special script.

[1] "(Yes, the double-function call is slow, but if you wanted fast, you wouldn't be using objects at all, eh? :-)" -tchrist in perltoot.

[2] Perl guys, I'm looking at you.

This discussion has been archived. No new comments can be posted.

The clash of two cultures

Comments Filter:

Anyone can make an omelet with eggs. The trick is to make one with none.

Working...