Earlier quoted context omitted.
I've hardly used it myself, but apparently Microsoft's PowerShell pipes typed objects between processes: http://technet.microsoft.com/en-us/library/dd347728.aspx
Actually, not between processes - all Powershell commands run in the same address space as the shell, and must be implemented in .Net. I don't think you can easily write an external process which takes a Powershell object directly as input.
Rich Command Shells
81–90 of 101 posts
Re: Rich Command Shells
#82Earlier quoted context omitted.
> in the other corner: the complaint that sometimes, people can put carriage returns in their filenames and screw up the output of `ls -1`. With no suggestion of what would replace composed functional streams. How about functions that operate on data structures such as lists and maps? These can include generic functions that can slice and dice data structures regardless of what type of data those structures contain.…
The unix dataset already works on list and map data structures. lists: ls -1 | wc -l maps: ps -ef | grep 'tobekilled' | grep -v grep | awk '{ print $2 }' | xargs kill would unix be better if it were cwd.files.count and processes.filter{name = 'tobekilled'}.map(kill) ? maybe for the newbie who paradoxically already understands functional and object-oriented programming, I'll grant. But the 'pipe' ("this is a bucket br…
versus
> processes.filter{name = 'tobekilled'}.map(kill)
Yes, actually, I would like the second one better (although I know it's only pseudo-code). To me, the most egregious problem with the Unix way of doing this is exemplified by the "grep -v grep" part. The first grep command didn't specify precisely what you wanted, i.e. the subset of processes whose executable name (or argv[0]) is "tobekilled". It can't, because ps produces lines of text intended primarily to be displayed on a terminal and read by a human, and grep merely searches those lines of text for a substring. It's all a very lossy process. So you had to add a second grep to work around the fact that the first grep also matched a particular occurrence of "tobekilled" in a command-line argument other than argv[0]. But what if someone were running "vim tobekilled.txt" at the same time? These sorts of workarounds are to Unix as epicycles were to Ptolemaic astronomy -- evidence that the foundation is flawed.
> maybe for the newbie who paradoxically already understands functional and object-oriented programming, I'll grant.
I think it would be easier to teach the fundamentals of functional programming -- not the crazy academic type-theory stuff, but basics like map and filter -- than all the intricacies and gotchas of combining Unix tools like grep, sed, cut, xargs, awk, and so on. You do realize that, in addition to the shell language itself, you casually dropped in a whole second language (Awk) in your second example, right?
> The Lennart bit was a joke. The OP's post was so histrionically overwrought that I responded sardonically. Apologies if you were offended.
It bothers me that you used Lennart's name as a synonym for "anti-Unix", as if that's his most salient characteristic (if it's even true of Lennart). How do you think he would feel about that "joke" if he read it? Especially on top of all the other vitriol he's received?
Re: Rich Command Shells
#83Earlier quoted context omitted.
> Take a read of some of the earlier threads on HN about Shellshock, and you will find numerous people blaming Apache for not "escaping" the data it was putting in a shell variable. It seems to me that this is the result of Cargo Cult Programming. People know that SQL strings, and user input need to be 'escaped,' so they just think "Obviously this needs to be escaped too! It's user input!" Yet they don't realize that…
SQL injection is not avoided by escaping arguments, but by never mixing the command and user supplied arguments in the first place. The equivalent to your example would be execlp("mv", "mv", src, dest, NULL); which does not rely on the shell to try to untangle your arguments from a single string. Edit: Fixed, thanks!
People see:
execute("select * from table where id = ?", id);
as for the most part like: execute(sprintf("select * from table where id = '%s'", escape(id)));
Where `escape()` is written by "smarter people" and makes sure that `id` isn't a string like this: 0'; delete all from user;'
(e.g. turning it into `0''; delete all from user;''`). I realize that this isn't what actually happens, but the general idea is that you are sanitizing your inputs.Re: Rich Command Shells
#84Earlier quoted context omitted.
The unix dataset already works on list and map data structures. lists: ls -1 | wc -l maps: ps -ef | grep 'tobekilled' | grep -v grep | awk '{ print $2 }' | xargs kill would unix be better if it were cwd.files.count and processes.filter{name = 'tobekilled'}.map(kill) ? maybe for the newbie who paradoxically already understands functional and object-oriented programming, I'll grant. But the 'pipe' ("this is a bucket br…
I'm honestly not sure if your post is meant to be satire or not. >lists: ls -1 | wc -l The computer has taken a real array (probably an array in C), joined all the items together into one big string using magical characters as dividers, and then split it again on those magic characters to try and reconstruct the metadata that it threw away. I think the problem is pretty obvious and well known. >would unix be better i…
The devil is in the details. In OP's example, is "files" a field of "cwd," and "count" a field (or getter) of "files?" Is "filter" a method of "processes" and "map" a method of the resulting (implicit) list returned by "filter"?
If the answer to any of these is "yes," then you will find yourself needing to implement these fields and methods (and probably others) for each OS object. The "filter" in "processes" necessarily has a different implementation from "filter" in "files", since despite having the same external interface, they both operate in different contexts on different internal state (i.e. a process object is not a file object).
Contrast this with the UNIX approach, where the "filter" and "map" implementations (i.e. grep, awk, sed, tr) exist independent of OS-level objects (i.e. processes, files, semaphores, sockets, etc.) and their state, allowing them to be developed and improved independently of one another and the data they operate on.
You want there to be some notion of type safety and structure in IPC. This can already be achieved: simply rewrite your programs to communicate via asn.1, json, or protobufs, or some other common structured marshalling format. You can have ls send wc an array of strings, instead of having wc guess which bytes are strings by assuming that whitespace delimits them.
However, upon doing this, you will find that you will only be able to use wc with programs that speak wc's protocol. Now if you're lucky, you can convince everyone who wants to send data to wc to use the new protocol. If you're unlucky, you'll instead end up with a bunch of programs that only implement it partially or with bugs. If you're really unlucky, there will also be competing versions of the wc protocol. Moreover, what about programs that wc will need to pipe data to? wc will need to know how to communicate with all of them as well.
My point is, if we go the route of imposing structure and types on IPC, the only thing you'll have to show for it are O(N^2) IPC protocols for N programs, which they all must implement perfectly (!!) to get type safety. Want to write a new program? Now you also have to write O(N) additional IPC protocols so it can communicate with the others.
Maybe you can additionally mandate that each program speaks the same IPC protocol (i.e. there is One True Record for piping data in, and One True Record for piping data out). But, if this IPC protocol encompasses every possible use-case, how is it any different than a byte stream?
Re: Rich Command Shells
#85Earlier quoted context omitted.
True, such a feature should really be system-wide - something like OSX's Automator, maybe. That doesnt take away from the point, however, that GUI actions can be stored in history, composed, etc.
But right now, they aren't. :)
Re: Rich Command Shells
#86Given all of that, and also Oberon -- '80s too, and even the Engelbart's Demo -- '68!, I totally every day wonder and can't understand why in 2010's all of the "modern" OSes still provide the developer just with text-only consoles??... okay, maybe for end-users there was a jump (in interfaces and features), and maybe it was significant indeed (movies editing, 3d modelling/sculpting, possibility of instant communicati…
That's a very interesting question. I'd guess that the technical decisions that differentiated early unix from the lisp machines etc. were based on hardware and cost limitations.(the development of unix is something I'd be interested in reading more about) Then as unix took off, these technologies became entrenched, with a kind of apologetics developing amongst users who liked those systems, or never used anything el…
In fact, I started hearing of all of those OSes fairly recently too, but I still see myself as a "youngster" in programming world, and thus I thought those technologies were more well known at that time. Also, that they were more well known to Important Figures and Big Companies then, so they could try to build on those ideas.
But now I start to recall, that most of those OSes are usually reported to be used and deployed quite rarely (Lisp Machines e.g. often dismissed because of high price and hardware requirements), so that could have limited their exposure. And also, I'm ashamed to admit I forgot about this (oh the times!), it must be taken into account that there was no Internet at the time, so this also made sharing of ideas harder than now...
Re: Rich Command Shells
#87Earlier quoted context omitted.
> in the other corner: the complaint that sometimes, people can put carriage returns in their filenames and screw up the output of `ls -1`. With no suggestion of what would replace composed functional streams. How about functions that operate on data structures such as lists and maps? These can include generic functions that can slice and dice data structures regardless of what type of data those structures contain.…
The unix dataset already works on list and map data structures. lists: ls -1 | wc -l maps: ps -ef | grep 'tobekilled' | grep -v grep | awk '{ print $2 }' | xargs kill would unix be better if it were cwd.files.count and processes.filter{name = 'tobekilled'}.map(kill) ? maybe for the newbie who paradoxically already understands functional and object-oriented programming, I'll grant. But the 'pipe' ("this is a bucket br…
How about
file:. count
?Re: Rich Command Shells
#88If you come to Freiheit.com next week (16. Oct 2014) to the Clojure User Group Meeting in Hamburg/Germany, I'll demo the Dynamic Windows user interface of a real Symbolics Lisp Machine. Including its command shell called 'Dynamic Lisp Listener'. http://www.meetup.com/ClojureUserGroupHH/events/207314372/
Cool! Do you know if the demo will be recorded?
https://www.youtube.com/watch?v=o4-YnLpLgtk
the AI winter is something you don't hear too much about. http://en.wikipedia.org/wiki/AI_winter
Re: Rich Command Shells
#89Earlier quoted context omitted.
The unix dataset already works on list and map data structures. lists: ls -1 | wc -l maps: ps -ef | grep 'tobekilled' | grep -v grep | awk '{ print $2 }' | xargs kill would unix be better if it were cwd.files.count and processes.filter{name = 'tobekilled'}.map(kill) ? maybe for the newbie who paradoxically already understands functional and object-oriented programming, I'll grant. But the 'pipe' ("this is a bucket br…
> ps -ef | grep 'tobekilled' | grep -v grep | awk '{ print $2 }' | xargs kill versus > processes.filter{name = 'tobekilled'}.map(kill) Yes, actually, I would like the second one better (although I know it's only pseudo-code). To me, the most egregious problem with the Unix way of doing this is exemplified by the "grep -v grep" part. The first grep command didn't specify precisely what you wanted, i.e. the subset of p…
Can we do better? Sure! One could imagine a reformation of the unix philosophy to center around strongly typed streams that could totally work after you put about 20 years of effort into replacing the existing tools. All too often, though, the reformers are people who don't understand the philosophy and want to try a weird collection of ad-hockery instead.
Re: Rich Command Shells
#90Earlier quoted context omitted.
SQL injection is not avoided by escaping arguments, but by never mixing the command and user supplied arguments in the first place. The equivalent to your example would be execlp("mv", "mv", src, dest, NULL); which does not rely on the shell to try to untangle your arguments from a single string. Edit: Fixed, thanks!
> SQL injection is not avoided by escaping arguments, but by never mixing the command and user supplied arguments in the first place. People see: execute("select * from table where id = ?", id); as for the most part like: execute(sprintf("select * from table where id = '%s'", escape(id))); Where `escape()` is written by "smarter people" and makes sure that `id` isn't a string like this: 0'; delete all from user;' (e.…
can we stop with this please? I'm sure it's not your intention and it's the way it's always phrased but it's casual contempt and we deserve to treat each other and be treated better.
"escape() is written by someone who spent the large amount of time analysing all the issues, testing, taking and incorporating feedback so the rest of us, who are both smart and competent, don't have to duplicate the work.