Home Flight manual Ramblings Tags RSS

Redirection 101: the very basics

Table of contents

Disclaimer: this article is tailored to those of us who are taking their first steps in the CLI.
A seasoned user is still likely to find some quite interesting information in the various notes, but the main focus of the article still is only meant to level the playing field in order to approach the everything is a file series.

Redirection

Straight from bash's manual, we learn that before a command is executed, its input and output may be redirected using a special notation interpreted by the shell.
There is a lot to talk about here: redirection allows commands' file handles to be duplicated, opened, closed, made to refer to different files, and can change the files the command reads from and writes to; but I'll stick here to the practical, day-to-day uses of redirection.

Instead of manually typing up on stdin, you may redirect some other I/O stream to sort's standard input. Just as well, you may redirect its output to an any other file descriptor using one (or more!) of five (or 6, with the HERESTRING Bashism) redirection operators:

Let's explore the few things to know about each.

Input redirection: <

The dead simple < operator redirects a file descriptor to FD 0. Whereas sort invoked on its own would have you type your input, you may have it sort the files of a file on disk instead:

sort < unsorted.txt
A pricot
B anana
C oconut
D ragonfruit
this uses unsorted.txt as standard input
D ragonfruit
C oconut
A pricot
B anana

It may take a FD number, too, to redirect to a file descriptor other than 0, the standard input. For instance, you may redirect FD 3 to the contents of unsorted.txt:

sort 3< unsorted.txt

The above is of dubious interest, since sort doesn't do anything with its FD 3.

nb.: Going forward, I'll invoke sort with a file descriptor as its first positional argument, which will have it read from there instead of stdin.

Output redirection: >

A counterpart to <, the > operator redirects a file descriptor to FD 1. Whereas sort invoked on its own would print its output to the terminal, you may have it write the sorted output to a file on disk instead:

sort unsorted.txt > sorted.txt
this has no visible output, since stdout was redirected to sorted.txt
D ragonfruit
C oconut
A pricot
B anana
A pricot
B anana
C oconut
D ragonfruit

Just like <, it may take a FD number, to redirect to to another descriptor. A fairly common use case is to redirect FD 2, the standard error output, to a file, so that you can inspect it later:

sort unsorted.txt 2> errors.txt
A pricot
B anana
C oconut
D ragonfruit
errors.txt would contain any error output

You may redirect both stdout and stderr at the same time, using the &> operator, though it is not POSIX-compliant.

Appending output: >>

The >> operator is similar to >, but appends to the file descriptor instead of overwriting it. This is useful when you want to keep the previous contents of a file and add new data to it, rather than replacing it.

It also understands a file descriptor number, like the two operators above.

Here Document: <<

The << operator redirects a here document (abbreviated HEREDOC) to FD 0. A here document is a way to provide input to a command directly within the script or command line, rather than from a separate file. For instance, you can use it to sort a list of items without having to create a separate file:

sort <<EOF
C oconut
D ragonfruit
A pricot
B anana
EOF
A pricot
B anana
C oconut
D ragonfruit

Once again, it may take a file descriptor number, to redirect to a file descriptor other than 0, the standard input. There are a few more things that make HEREDOC uniquely useful, which I go over in a complementary article.

Here String: <<<

Disclaimer: this one is not part of the POSIX standard.

The <<< operator redirects a here string to FD 0. A here string is a way to provide a single line of input to a command directly within the script or command line, rather than from a separate file or a here document. For example, you can use it to sort a single line of text:

sort <<< '
C oconut
D ragonfruit
A pricot
B anana
'
A pricot
B anana
C oconut
D ragonfruit
<<< isn't part of the POSIX specification
sort <<< $'\nC oconut\nD ragonfruit\nA pricot\nB anana'
A pricot
B anana
C oconut
D ragonfruit
<<< and $'...' make this doubly non-POSIX

Since you'll already be using Bashisms if you're there, you may like to know that the $'...' (ANSI-C quoting) allows you, in bash, zsh and other popular interactive interpreters, to interpret backlash escape sequences much like C string literals would. There, \n is a linefeed, \t a tabulation, \x20 is a byte with the hexadecimal value 20 (a whitespace), \u20AC is the Unicode character with code point U+20AC (the Euro sign), and so on.

Command piping: |

The | operator pipes the standard output (stdout, FD 1) of one command to the input (stdin, FD 0) of another. Simple, obvious, effective; this lets you chain commands together, passing the output of one command as input to the next. We talk then of pipeline, as opposed to simple commands; though these terms appear more in the literature than in the day-to-day vernacular.

For example, you can use it to sort a list of items generated by another command:

printf 'C\nD\nA\nB' | sort
A
B
C
D
the \n are interpreted by printf and therefore aren't non-POSIX constructs here!

And there we are! The basics of redirection in the shell; nothing much fancy, but one learns to walk before they run and walking, however mundane, does get fairly practical once mastered.