36.7 Process Substitution: <() and >()

Right, so you’ve got pipes (|) down. You can send stdout from one command to stdin of another. It’s brilliant, it’s simple, it’s the Unix philosophy in a single character. But what if you need to send the output of a command to a program that expects a filename as an argument, not a stream? You can’t pipe into that. You’d have to save it to a temp file first, which is a hassle.

36.6 tee: Splitting stdout to File and Terminal Simultaneously

Right, so you’ve got a command that’s about to spew a glorious, information-dense stream of data to your terminal (stdout). You want to capture that stream to a file for posterity (or debugging, or your boss), but you also want to watch it scroll by in real-time to make sure it’s not doing something catastrophically stupid. Your first thought might be to just redirect the output: my_command > output.log. Great. Now you have a file. And you also have the profound silence of a command that ran and told you absolutely nothing. You’re flying blind. Did it work? Is it hung? Who knows! You’re not a psychic.

36.5 Pipes (|): Connecting stdout to stdin

Right, let’s talk about the pipe. This little vertical bar (|) is arguably the single most elegant and powerful piece of punctuation in the entire shell universe. It’s the duct tape of the command line, and I mean that in the most respectful way possible. It takes the gushing firehose of text from one program’s standard output (stdout) and plugs it directly into the next program’s standard input (stdin). No temporary files, no manual copy-pasting, just a clean, direct connection.

36.4 < and <<: Input Redirection and Here Documents

Right, let’s talk about getting data into your commands. You already know that > is for sending output somewhere else, like a file. Well, < is its less-famous but equally brilliant cousin for pulling input from somewhere else. It’s the difference between a command shouting into a megaphone and one listening through a stethoscope. Think of most commands as lazy teenagers. They’ll just sit there, waiting for you to type input directly into them (from stdin, the standard input stream). But with <, you can pre-record your lecture and play it right into their ears. You’re redirecting a file to be the command’s input, saving you the tedious work of typing it all out manually.

36.3 2> and 2>&1: Redirecting stderr

Right, so you’ve mastered the art of throwing standard output (stdout) into a file with a simple >. Feels good, doesn’t it? You run a command, it does its thing, and you get a nice, clean log file. Then you run something that blows up spectacularly, you check your beautiful log file, and… it’s empty. The crushing silence of a command that failed without a trace. All those glorious, helpful error messages went straight to the bit bucket in the sky because you forgot about stderr.

36.2 > and >>: Redirecting stdout to Files

Right, let’s talk about making your terminal commands stop yelling into the void and start writing things down. By default, when a command runs, its standard output (stdout)—the regular, expected results—just gets printed to your screen and then vanishes into the ether. Useful for one-off glances, useless for, well, everything else. This is where the > operator comes in. It’s your command-line bouncer, grabbing stdout by the collar and redirecting it to a file you specify.

36.1 stdin (0), stdout (1), stderr (2): The Three Standard Streams

Right, let’s talk about the three little file descriptors that run the universe. Forget APIs, forget web servers—the real magic of Unix and Linux happens in these three ancient, fundamental data streams. They’re the primordial ooze from which all command-line life evolved, and if you don’t understand them, you’re just poking at the keyboard with a stick. Every single process you launch is automatically handed three open files: one for input, one for output, and one for dumping its complaints. We call them standard input (stdin), standard output (stdout), and standard error (stderr). Their file descriptors are 0, 1, and 2, respectively. These aren’t suggestions; they’re a contract the operating system enforces. When you run ls, it writes its beautiful list of files to descriptor 1. If it can’t read a directory, it writes its angsty error message to descriptor 2. It’s this separation of church and state—the good stuff from the bad—that makes the whole system so powerful.

— joke —

...