4 ms·
...how ? It's called pipe, not "infinitely large buffer that will wait indefintely till the command ends to pass its output further"
by adql 3y ago
...how ? It's called pipe, not "infinitely large buffer that will wait indefintely till the command ends to pass its output further"
- shiomiru 3y agoDOS also has a "pipe", which works exactly like that. (Obviously, since DOS can't run multiple programs in parallel.)
- zamfi 3y agoCan’t speak for OP, but one might reasonably expect later stages to only start execution once at least some data is available—rather than immediately, before any data is available for them to consume. Of course, there many reasons you wouldn’t want this—processes can take time to start up, for example—but it’s not an unreasonable mental model.
- OJFord 3y agoNot even that they might be particularly slow to start in absolute terms, but just that they might be slow relative to how fast the previous stage starts cranking out some input for it. (Since, as GP said, not an infinite buffer.)
- Joker_vD 3y agoWell, it could be implemented like this, it's just more cumbersome than "create N-1 anonymous pipes, fork N processes, wait for the last process to finish": at the very least you'll need to select() on the last unattached pipe, and when job control comes into the picture, you'd really would like the "setting up the pipeline" and "monitoring the pipeline's execution" parts to be disentangled.
- hawski 3y agoI know this about Unix pipes from a very long time. Whenever they are introduced it is always said, but I guess people can miss it. Though now I will break your mind as my mind was broken not a long time ago. Powershell, which is often said to be a better shell, works like that. It doesn't run things in parallel. I think the same is to be said about Windows cmd/batch, but don't cite me on that. That one thing makes Powershell insufficient to ever be a full replacement of a proper shell.
- MatejKafka 3y agoNot exactly. Non-native PowerShell pipelines are executed in a single thread, but the steps are interleaved, not buffered. That is, each object is passed through the whole pipeline before the next object is processed. This is non-ideal for high-performance data processing (e.g. `cat`ing a 10GB file, searching through it and gzipping the output), but for 99% of daily commands, it does not make any difference. cmd.exe uses standard OS pipes and behaves the same as UNIX shells, same as Powershell invoking native binaries.
- hawski 3y agoOh, that's what I missed! I managed to find out about it while trying to do an equivalent of `curl ... | tar xzf -` in Powershell. I was stumped. I guess the thing is that a Unix shell would do a subshell automatically.
- poizan42 3y ago> Though now I will break your mind as my mind was broken not a long time ago. Powershell, which is often said to be a better shell, works like that. It doesn't run things in parallel. I think the same is to be said about Windows cmd/batch, but don't cite me on that. That one thing makes Powershell insufficient to ever be a full replacement of a proper shell. A Pipeline is PowerShell is definitely streaming unless you accidentally forces the output into a list/array at some point, e.g. try this for yourself (somewhere you can interrupt the script obviously as it's going to run forever) class InfiniteEnumerator : System.Collections.IEnumerator { hidden [ulong]$countMod2e64 = 0 [object] get_Current() { return $this.countMod2e64 } [bool] MoveNext() { $this.countMod2e64 += 1 return $true } Reset() { $this.countMod2e64 = 0 } } class InfiniteEnumerable : System.Collections.IEnumerable { InfiniteEnumerable() {} [System.Collections.IEnumerator] GetEnumerator() { return [InfiniteEnumerator]::new() } } [InfiniteEnumerable]::new() | ForEach-Object { Write-Host "Element number mod 2^64: $_" } Whether it runs in parallel depends on the implementation of each side. Interpreted powershell code does not run in parallel unless you run it a job, use ForEach-Object -Parallel, or explicitly put it on another thread. But the data is not collected together before being sent from one step from the next.
- lylejantzi3rd 3y agoPipe, |, was also commonly used as an "OR" operator. I wonder if the idea that you could "pipe" data between commands came later.
- hawski 3y agoI think the math usage was first. i.e. absolute value: |x|
- adrian_b 3y agoThe language APL\360 of IBM (August 1968) and the other APL dialects that have followed it have used a single "|" as a monadic prefix operator that computes the absolute value and also as a dyadic infix operator that computes the remainder of the division (but with the operand order reversed in comparison with the language C, which is usually much more convenient, especially in APL, where this order avoids the need for parentheses in most cases).
- samatman 3y agoNot to get all semiotic about it, but |x| notation is a pair of vertical lines. I'm sure that someone has written a calculator program where two 0x7D characters bracketing a symbol means absolute value, but if I've ever seen it, I can't recall. Although 0x7D is overly specific, since if a sibling comment is correct (I have no reason to think otherwise), | for bitwise OR originates in PL/1, where it would have been encoded in EBCDIC, which codes it as 0x4F. I'm not really disagreeing with you, the |abs| notation is quite a bit older than computers, just musing on what should count as the first use of "|". I'm inclined to say that it should go to the first use of an encoding of "|", not to the similarly-appearing pen and paper notation, and definitely not the first use of ASCII "|" aka 0x7D in a programming language. But I don't think there's a right answer here, it's a matter of taste. Because one could argue back to the Roman numeral I, if one were determined to do so: when written sans serif, it's just a vertical line, after all. Somehow, abs notation and "first use of an encoded vertical bar" both seem reasonable, while the Roman numeral and specifically-ASCII don't, but I doubt I can unpack that intuition in any detail.
- adrian_b 3y ago
- arp242 3y agoUsually mental models develop "organically" from when one was a n00b, without much thought, and sometimes it can take a long time for them to be unseated, even though it's kind of obvious in hindsight that the mental model is wrong (e.g. one can see that from "slow-program | less", and things like that).
- maicro 3y agoI think a main reason for this is that you can have a "good enough" working mental model of a process, that holds up to your typical use cases and even moderate scrutiny. It's often only once you run into a case where your mental model fails that you even think to challenge the assumptions it was built on - at least, this has been my experience.
- deleted 3y ago[deleted]
- m000 3y agoThat is called a sponge! SPONGE(1) moreutils SPONGE(1) NAME sponge - soak up standard input and write to a file SYNOPSIS sed '...' file | grep '...' | sponge [-a] file DESCRIPTION sponge reads standard input and writes it out to the specified file. Unlike a shell redirect, sponge soaks up all its input before writing the output file. This allows constructing pipelines that read from and write to the same file.