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:
<redirectsstdinfrom a file descriptor>redirectsstdoutto a file descriptor>>appendsstdoutto a file descriptor<<redirectsstdinfrom an in-line document (HEREDOC)<<<redirectsstdinfrom an in-line string (HERESTRING, non-POSIX!)|pipesstdoutfrom a command tostdinof another
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:
A pricot
B anana
C oconut
D ragonfruit
unsorted.txt as standard inputD 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:
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:
stdout was redirected to sorted.txtD 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:
A pricot
B anana
C oconut
D ragonfruit
errors.txt would contain any error outputYou 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:
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:
A pricot
B anana
C oconut
D ragonfruit
<<< isn't part of the POSIX specification
A pricot
B anana
C oconut
D ragonfruit
<<< and $'...' make this doubly non-POSIXSince 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:
|
A
B
C
D
\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.