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...
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.
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 ;)
> 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:
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:
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.
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'.
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...