7 ms·
Your terminal is not a terminal: An Introduction to Streams
- mStreamTeam 8y agoThis is a great article and very beginner friendly as well. While I didn't learn anything new from this, it helped me organize the concepts in a way that would be much easier to communicate with someone else. Thanks for posting. I bookmarked this incase I ever need to explain streams to someone.
- vcavallo 8y agogreat stuff! minor editing note: the first time > is mentioned there is no 1 with it. a bit further down you say “we can drop the 1 from >”.
- GorgeRonde 8y agoI'm frankly tired of the less is more, simple > complex fad. It's understandable this mindset is so trendy: it's easier. And then what ? Showcase another pointless note taking app ?
- Retra 8y agoThe idea is not to be driven by simplicity per se, but by composability. Build software wherein you take it for granted that it will be used in many contexts, and that it is only ever able to solve 'part' of the problem because other parts may not yet be understood. If you're not focussed on building simple systems, then you're unlikely to be able to compose them, and if you can't compose them, they will likely become obsolete quickly. So the goal is really to avoid having to implement the same things over and over again.
- GorgeRonde 8y agoYes sorry, I totally agree with this and I am digressing. I'm reacting to the first words of the article: > I always try to build less software. Less software means you have to spend less time updating it, less time fixing it, and less time thinking about it. The only thing better than “less software” is no software at all. The problem is that I have been harassed on this very basis (i.e. that of a philosophically stated point of view) by people that are less able than me and this lead to writing over and over again the same dumb code for 15,000 lines while it could have been kept under 1000 (in fact I did it) (and as you may have already guessed it, this is resentment speaking here). Actually you don't make things simpler, either you move complexity around, often concentrating it somewhere to alleviate its weight on other parts of the system, and they can then be described in shorter terms, enhancing the pace at which you can tweak them – or you get rid of that complexity, moving it out of the code, i.e. delegating it to future implementations or to manual maintenance support tasks. This is the bit that is problematic to me: > [you have to spend] less time thinking about it Absolutely not. In some parts yes, definitively, but some other parts will be incredibly dense, and will require a very slow reading pace. When you want to change such code, you have to sit in front of your screen, thinking hard about what happens for 30 minutes, and when you get it it's a 5 lines change. Maybe the author doesn't consider this in this article because he doesn't have to deal with implementing these piping heuristics, he already has those of bash. Now why am I pulling the cow's horn like this ? Because this also encourages people into simpler thinking and they mix this up with whatever noble ideal simplicity actually refers to, while, as Hickey pointed out, it's a lot more about the tradeoff that populate the quadruality between easy/simple vs complex/complicated. Nonetheless, here they come, shitting on my tree-traversal – not a simple thing, not in their realm, and here they are, "flattening" it in a 200 files long pull request. As for how software should be done, err ... I think I never heard what I'd say, i.e. that software should be developed by programmers or in other words teammates, not pupils nor slaves, and that these people, as thinking beings, shouldn't be treated as things that conform and must be, quite to the contrary, they should let be.
- empath75 8y agoFad? That’s the Unix philosophy going back 50+ years.
- bloopernova 8y agoI've shared this with my team, it's super useful as an introduction and reference to terminals for a wide range of folks.
- trw999 8y agohttps://www.linusakesson.net/programming/tty/ https://www.linusakesson.net/programming/tty/ mentioned at the bottom of the article is a must read as well.
- armitron 8y agoThere are too many mistakes and typos in this to recommend it. Better if you go straight to the end and click on "TTY demystified" and the other links he recommends.
- tyingq 8y agoThis is interesting to compare to the 3270 terminals in mainframes. On those the terminal inherently understands labels and fields, and typing doesn't necessarily go to the host until you submit. It's closer to a web browser than a Unix style terminal.
- neilv 8y agoWhen I was working on one open source terminal library, I wanted to get a 3270 family terminal (with appropriate bridge for TCP/IP or RS232), just to look for ideas that were lost to the Unix and other communities I already know. I understand some other, more generic serial terminals, like were used on Unix, also had block modes (local editing of screen regions), but I'm not aware of Unix software taking advantage of that.
- neilv 8y agoThe article doesn't get into the few ways that terminals are more than normal stdio streams, but it turns out you can do a lot without knowing any of that. For one terminal library I made, I was able to avoid any extra native code in the process, using only unbuffered streams and a kludgey call out to `/bin/stty` to set raw input on that end. (Next time, I'd probably just do FFI to native code.) https://www.neilvandyke.org/racket/charterm/ https://www.neilvandyke.org/racket/charterm/
- kurtisc 8y agoRecently I broke my terminal emulator's config while I didn't have an internet connection so I had to use a virtual terminal to fix it. It made me wonder, does anybody use virtual terminals as their daily drivers?
- JasonFruit 8y agoI did for about six months, and then decided it was more trouble than the experiment had fun potential. I ran GNU screen, emacs with eww and every other special get-stuff-done mode, FBI, fbgs, and a few other tools like that, and while I got it working okay, it was never a pleasure to use.
- jolmg 8y agoAs in not starting an X server? No. As in most of the time the window focus is on a terminal? Yes. In my computer, 90% of the time there are only 2 types of windows open. 1 is the web browser, and the other is the terminal. Sometimes I open up Emacs to read my mail or write some notes in org-mode, but my text editor of choice is vim in a terminal, not even gvim.
- kurtisc 8y agoNot that (which is similar to my setup), I mean tty[0-6] which come up when you press ctrl-alt-F[1-6]
- jolmg 8y agoFor a daily driver... it's hard to imagine the conditions where that would be better than using X. Maybe if one's stuck with a machine so old (like 90's old) where even light window managers lag, then maybe. You normally wouldn't install X on servers or raspberry-pi's or other purpose built machines like routers, but you also wouldn't use them as a daily driver. I imagine even people that need to work on those extensively would rather log-in via ssh from their real daily-driver.
- Izkata 8y ago"A Day Without X" [0] may interest you. [0] http://www.terminally-incoherent.com/blog/2007/05/21/a-day-without-x/ http://www.terminally-incoherent.com/blog/2007/05/21/a-day-w...
- sorryimissedit 8y agoThe cat example is missing an arrow. Clearly, you see everything twice. So somehow the input also goes around cat and directly to the output.
- boromi 8y agoSo `cat /tmp/hello.txt` does not read stdin from `/tmp/hello.txt`? Why does `cat /tmp/hello.txt` set stdout to `/tmp/hello.txt` this is confusing Also his example ` exec 5<> /tmp/lines.txt` fails with ambiguous redirect.
- laumars 8y ago> So `cat /tmp/hello.txt` does not read stdin from `/tmp/hello.txt`? Why does `cat /tmp/hello.txt` set stdout to `/tmp/hello.txt` this is confusing While stdin, out and err are files, they're not really the same thing as a /tmp/hello.txt type file you're thinking of. They're file system objects with special permissions. And while the idea is you'd use normal file read / writing APIs on them they're really more like FIFO buckets (technically it's a symlink to a file - for reasons that will make more sense shortly) Take the example: cat /tmp/hello.txt | grep world (ignoring for the moment the "abuse of cat" for the sake of this example) So what would happen there `cat` would write to this bucket (the location of it varies from one OS to another) and another process in the pipe (eg `grep`) would read from that same bucket. But from the perspective of `cat` it's STDOUT and from the perspective of `grep` it's STDIN - even though they're the same file. Things get a little more complicated when you start talking about redirection but essentially because each programs STDIN, STDOUT and STDERR file is actually just a symlink, when a program starts it's symlink points to another file instead of the normal one that would be next (or previous) in the pipeline. However this is all done automatically by the OS when you make the syscalls. Things get even more complicated when you start talking about stuff that is read from or written to your terminal because they will be slightly different file system objects again but with a bit set to identify them as a pseudo-TTY. It's not really worth getting into the mechanics of it here. However ostensibly the principle is the same as the above. edit: rewritten for clarity
- boromi 8y agoI see, and thank you for the clarification. My main problem then is the blog post for the redirection section is poorly written and plain wrong with regards to the examples and pictures. Their example is $ cat /tmp/root_content.txt And then in the picture the show that the `cat` program's stdout is `/tmp/root_content.txt`, which is incorrect according to your description. This would only be correct if it was then redirected or piped.
- tedunangst 8y agoWas expecting this to be about https://en.wikipedia.org/wiki/STREAMS https://en.wikipedia.org/wiki/STREAMS
- chasil 8y agoI wasn't aware of the issues behind SysV STREAMS. Thank heavens that Alan Cox flat out refused. http://www.groklaw.net/articlebasic.php?story=2006070309564374 http://www.groklaw.net/articlebasic.php?story=20060703095643...
- dfox 8y agoThe original idea behind streams is decidedly more Unix-like than the whole BSD sockets hack. Also it is only partially relevant to networking, conceptually it is generalization of the concept of line discipline, IIRC the original implementation of PTYs in SysV was layered on top of streams. Well, then there was X/Open and another standardization bodies who though that ISO OSI stack is a good thing (you have to be standards body to be capable of believing that) standardized STREAMS (note the capitalization) and build ISO OSI API in terms of that, complete with userspace layer in between that hides all the complexity in order for the thing to be actually usable.
- jolmg 8y agoThis is a good article, but this bit irks me: $ printf "Look, I have something inside" > /tmp/careful.txt $ cat /tmp/careful.txt Look, I have something inside $ printf "\nNow I have one more thing" >> /tmp/careful.txt $ cat /tmp/careful.txt Look, I have something inside Now I have one more thing $ What really happens is: $ printf "Look, I have something inside" > /tmp/careful.txt $ cat /tmp/careful.txt Look, I have something inside$ printf "\nNow I have one more thing" >> /tmp/careful.txt $ cat /tmp/careful.txt Look, I have something inside Now I have one more thing$ And what you want is: $ printf "Look, I have something inside\n" > /tmp/careful.txt $ cat /tmp/careful.txt Look, I have something inside $ printf "Now I have one more thing\n" >> /tmp/careful.txt $ cat /tmp/careful.txt Look, I have something inside Now I have one more thing $ Newlines are line terminators, not separators. This article missed what could have been a really good section on line buffering that could have explained some of the merit of having line terminators as opposed to line separators.
- klodolph 8y agoOne of the reasons that I like zsh, $ printf "Look, I have something inside" > /tmp/careful.txt $ cat /tmp/careful.txt Look, I have something inside% $ printf "\nNow I have one more thing" >> /tmp/careful.txt $ cat /tmp/careful.txt Look, I have something inside Now I have one more thing% $ Zsh will add the line break and mark its absence with a % with reverse video). I follow the "terminator-not-separator" rule religiously in my own source code, but my impression is that this is somewhat a Unix-ism.
- saagarjha 8y ago> my impression is that this is somewhat a Unix-ism This is how POSIX defines lines for text files.
- dfox 8y agoWhich defines it this way, because various original Unix components (including things like stdio) will break in various surprising and inconsistent ways when text file does not end in \n or contains lines longer than some arbitrary limit (which is why POSIX has LINE_MAX).
- crimsonalucard 8y agoWhat an attention grabbing first line but ultimately contradictory. If you hate software you hate streams because streams are software. Guess what? I hate computers. If you do less streaming across computers and put everything in a monolithic code base you need less computers. Is what I just said pointless, obvious and attention grabby? well so is the first couple lines of this article.
- zimbatm 8y agoRecently I needed to multiplex stdin to both stdout and stderr and was surprised that none of the coreutils tools supported that. The closest is `tee /dev/stderr` which only works on system where stderr is bound to that virtual device. It seems such a basic thing to do when you want to debug a pipe.
- amelius 8y agoDoes an OS/terminal/shell exist that allows one to apply a different interpretation to streams than as a stream of characters? For example JSON objects, or even images? Not sure how useful it would be, but it could look like this: $ cat car.png | grep "traffic-light" Illegal operation: stream is of type image $ cat car.png (image appears)
- detaro 8y agoPowershell does pipelining with streams of objects instead of only characters.
- TheCycoONE 8y agoUnfortunately it comes with risks. With byte streams you can have an arbitrary max buffer size after which the program has to wait to write. With objects you can run out of memory trying to pass everything in a single object. I hit this trying to generate large CSVs in powershell.
- deleted 8y ago[deleted]
- the_pwner224 8y agoI've heard MS PowerShell does this.
- jtokoph 8y agoiTerm2 kinda has the image option, but it's not a cat overload. https://www.iterm2.com/documentation-images.html https://www.iterm2.com/documentation-images.html
- valgaze 8y agoAwesome article! Handy maximum-portability redirection cheatsheet (write, append, discard): STDOUT (no number needed for file descriptor) command >stdout.txt command >>stdout.txt command >/dev/null STDERR (2 is required file descriptor) command 2>stderr.txt command 2>>stderr.txt # Append errors to file command 2>/dev/null # Discard stderr STDOUT + STDERR (separate destination) command >stdout.txt 2>stderr.txt command >>stdout.txt 2>>stderr.txt STDOUT + STDERR (duplicate destination, order matters) command >shared-output.txt 2>&1 #stderr follows stdout command 2>shared-output.txt >&2 #stdout follows stderr command >>shared-output.txt 2>&1 #append Practical example: npm install >npm-output.txt 2>npm-errors.txt #two destinations npm install >/dev/null 2>&1 #all output discarded
- leke 8y agoI thought this was something related to https://github.com/matz/streem https://github.com/matz/streem
- mesarvagya 8y agoI can see some Monads in his examples. One particular example being https://lucasfcosta.com/assets/fortune-and-cowsay-streams.png https://lucasfcosta.com/assets/fortune-and-cowsay-streams.pn...