Hacker News new | past | comments | ask | show | jobs | submit login

I feel I should mention Plan 9's pipeline branching. Not named pipes, but something which I guess served a significant subset of named pipes' use cases. The Plan 9 shell, rc, had a feature where when a subprocess was invoked with the syntax:

  <{ls}
that string would get replaced by a filename, which when opened would be hooked up to the stdout (or stdin for >) of the invoked command.

Used as an argument, this allowed you to essentially do none-linear piping in a mostly transparent way. I say mostly because I don't think you could seek.

Every once in a while I find myself wishing there was something like this in bash. Maybe there is...




In bash, that's referred to as process substitution[1]; the syntax is only slightly different:

    <(command)
Edit to add: both ksh and zsh support process substitution, too:

    ksh: <(command)
    zsh: either =(command) -- uses a temporary file
             or <(command) -- uses a named pipe
[1]: http://tldp.org/LDP/abs/html/process-sub.html


You shouldn't bring up Plan9 when discussing Linux.

It's akin to bringing up Mozart's writing symphonies at the age of 8 to the proud mother of a somewhat disabled child that has finally mastered the potty at the tender age of 12.

Seriously, you can literally list every single new IPC introduced in *nix in the last 3 decades and counter it with a better design and execution under Plan9. It's simply the result of a proper design as opposed to an afterthought. No real point in bringing it up unless you can constructively use the information to fix Linux.


Why? This seems like an issue that could be fixed in the shell---i.e. no need to involve any kernel design at all.


yea your comment certainly is constructive.


It's not. That's the point. You can't get constructive about this comparison. I suppose the only exception is to go the Wayland path and push IPC outside the kernel into the user land. At least there you can reason redundancy vs. redundant... But I honestly can't think of a single instance when that led to actual work getting done ;)


> You shouldn't bring up Plan9 when discussing Linux.

But the discussion isn't about Linux.


Wow. This is entirely incorrect on a simple, factual level.


you can run

  diff <(ls /path/to/dir/1) <(ls /path/to/dir/2)
in bash/zsh - im not sure if its a per executable thing or actually built into the shell?


ah, so you can! brilliant. thanks for that!


> im not sure if its a per executable thing or actually built into the shell?

It's built into the shell in zsh, and it must also be in bash. By way of explaining how I know, I am first going to tell you a little bit about the program called strace, but probably not backwards-talking little people:

http://en.wikipedia.org/wiki/Strace

When invoked like so:

    strace diff <(ls /path/to/dir/1) <(ls /path/to/dir/2)
strace positions itself between the running process which it invokes (in this case, diff) and the OS kernel. It then prints for you all of the communications traffic, in the form of system calls and return values, between the kernel and the process. Because it runs after the shell has expanded the command line, it gets to see the command line as the program sees it, as opposed to how it was typed.

Now, the output scrolls by pretty fast (there is a -o option to save the output to a file, which I neglected to bother with here), so I saw the end first:

    stat("/proc/self/fd/11", {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
    stat("/proc/self/fd/12", {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
    open("/proc/self/fd/11", O_RDONLY)      = 5
    open("/proc/self/fd/12", O_RDONLY)      = 7
and so on. Obviously, diff is getting information from /proc/self/fd/11 and /proc/self/fd/12. Weird. Where do those come from?

Scrolling up to the top of my xterm, we have the answer:

    execve("/usr/bin/diff", ["diff", "/proc/self/fd/11", "/proc/self/fd/12"], [/* 68 vars */]) = 0
You can look up execve for yourself; the upshot is, its second argument is the argv passed in to the process by the runtime environment, which reflects the command line after shell expansion. Thus, the <(ls foodir) stuff is a shell feature, and not per-command.


Or, more easily:

    echo <(:)


Ok, you're really going to have to explain that to me - what is (:) ? Or : for that matter!?



List your files and count them, too:

    ls -l|tee >(wc -l)
Works in bash, but not sh.


Nice example.

One minor correction I'd made though, it that you don't need '-l' in your 'ls' parameters as 'ls' automatically outputs one item per line when you're piping it's output, plus the '-l' option adds an additional line.

Though if you did still want to see the file permissions but have a correct line count then the following would crop the 1st line from 'ls -l':

    ls -l | sed 1d | tee >(wc -l)
Weirdly though, I thought 'ls' had an option to show a file count, but I can't find it in 'man'.


Not only did Plan 9 have named pipes, it lacked any other sort. Pipes were implemented as a synthetic filesystem.

  http://man.cat-v.org/plan_9_2nd_ed/3/pipe




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

Search: