As a student I have to use my shell everyday to get my work done. A shell can be an extremely powerful tool in everyday life if you know how to use it.
Shell redirections are something you have to use in order to accomplish many tasks without pain.
To output text on the terminal a program must write it's output into a file. The classical way to manipulate files on a UNIX-like operating system is by requesting to the OS a file descriptor (fd). An fd is an unsigned integer given by the OS that identifies a given file on the system.
File descriptors are numbers that represent a way to access files.
By default your program gets 3 file descriptors that are called
The first fd
stdin is the file used by your program to read input. It's default value is
0. If you start a program like
cat without arguments it reads its input from
The second fd
stdout is used to output content for the user (like "Hello World!"). It's default value is
The third fd open by default is
stderr. This one works exactly like
stdout except we mostly use it to output error messages. It's default value is
In a shell, there are a few operators to perform redirections. Those are
Those 3 operators have one main thing in common: They interact with input/output files.
>> are used to redirect output from a program into a file.
$> cat my_file.txt > my_new_file.txt # The output from cat is redirect to a file caled my_new_file.txt
(If the file does not exist, it is created)
The difference between
>> is that
> truncates the file it is outputing to and
>> appends to the output file.
$> echo Hello World! > greeting.txt # Creates a file with 'Hello World!' as the content $> echo How are you? >> greeting.txt # Append 'How are you?' to greeting.txt
< allows you to use a file as input. So
stdin becomes the file.
$> base64 < greeting.txt # base64 will use stdin as input which is redirected to greeting.txt by the shell
You can also combine multiple redirection operators:
$> cat < a.txt > b.txt # Reads from a.txt and outputs to b.txt
That one is a bit like the three above, except that it does not interact with files. Instead it is used to get input from the user's keyboard line by line.
So when you do something like:
$> cat <<EOF
... and press enter, the shell will expect input.
So you can continue:
$> cat <<EOF > Hello World! > How are you? > Do you know the answer to the ultimate question?
And when you want to stop the input you either press
Ctrl+D or type the word which is on the right side of the
<< operator (In this case
EOF) and press enter (it must be on an empty line):
$> cat << EOF > Hello World! > How are you? > Do you know the answer to the ultimate question? > EOF Hello World! How are you? Do you know the answer to the ultimate question?
Immediatly after the input has been stoppedt the shell runs the program with what you have typed as the content in
Those two do not act on files but file descriptors.
Their left side can be either ignored or be a number (the target fd).
The left side MUST be attached to the operator.
If I want to redirect
stderr I can do:
$> cat ft_strdup.c 1>&2
$> cat ft_strdup.c >&2
You can also use
<& to close a file descriptor (If you want to ignore error messages, for example)
$> find / -name 'lost_file' 2>&- # If you don't want to see messages like 'Permision denied'
The only difference between
<& is the default file descriptor used in case of a not given left fd.
>& is for
<& is for
Also, if you put a space between the left side of the operator and the operator itself the shell will think that the left side is actually an argument to pass to the program and will use the default left side fd number.
Those operators can be used anywhere on the command line
$> < input_file cat $> >output_file echo hello world $> ls 2>&- -R /
But you should put the them either on the beginning of the command or the ending to avoid confusion.
I hope this article has been helpful to you. :)
(open source and trusted by devs everywhere ❤️)