40

I understand that the > (right chevron) is for redirecting the STDOUT of a program to a file, as in echo 'polo' > marco.txt will create a text file called marco.txt with polo as the contents instead of writing it to the terminal output. I also understand the difference between that and a | (pipe), which is used for redirecting the STDOUT from the first command on the left of the pipe to the STDIN of the second command on the right of the pipe, as in echo 'Hello world' | less to show Hello world in the less view.

I just really don't understand how the < works. I tried marco.txt < echo 'polo' and bash gave me an error: -bash: echo: No such file or directory. Can someone explain how it works and why I'd use it?

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
jsejcksn
  • 596
  • 2
    Much like the > (left caret) the < (right caret) can be used to redirect stdin from a file to a program. – Rahul May 16 '16 at 07:43

2 Answers2

29

The operator < is most commonly used to redirect file contents. For example

grep "something" < /path/to/input.file > /path/to/output.file 

This would grep the contents of input.file, outputting lines containing "something" to output.file

It is not a full 'inverse' operator of the > operator, but it is in a limited sense with respect to files.

For a really good and brief description, along with other applications of < see io redirection

Update: to answer your question in the comments here is how you can work with file descriptors with bash using the < operator:

You can add additional inputs and/or outputs beyond stdin (0), stdout (1) and stderr (2) to a bash environment, which is sometimes more convenient than constantly switching where you are redirecting output. The #'s in the () next to the 3 'std' inputs/outputs in bash are their 'file descriptors' although they are rarely referred to in that way in bash - more often in C, but even then there are constants defined which abstract things away from those numbers, e.g. STDOUT_FILENO is defined as 1 in unistd.h - or stdlib.h...

Lets say you have a script that is already using stdin and stdout for interfacing with a user's terminal. You can then open additional files for reading, writing, or both, without impacting the stdin / stdout streams. Here's a simple example; basically the same type of material that was in the tldp.org link above.

#!/bin/bash -
#open a file for reading, assign it FD 3
exec 3</path/to/input.file
#open another file for writing, assign it FD 4
exec 4>/path/to/output.file
#and a third, for reading and writing, with FD 6 (it's not recommended to use FD 5)
exec 6<>/path/to/inputoutput.file

#Now we can read stuff in from 3 places - FD 0 - stdin; FD 3; input.file and FD 6, inputoutput.file
# and write to 4 streams - stdout, FD 1, stderr, FD 2, output.file, FD 4 and inputoutput.file, FD 6

# search for "something" in file 3 and put the number found in file 4
grep -c "something" <&3 >&4

# count the number of times "thisword" is in file 6, and append that number to file 6
grep -c "thisword" <&6 >>&6

# redirect stderr to file 3 for rest of script
exec 2>>&3

#close the files
3<&-
4<&-
6<&-
# also - there was no use of cat in this example. I'm now a UUOC convert.

I hope it makes more sense now - you really have to play around with it a bit for it to sink. Just remember the POSIX mantra - everything is a file. So when people say that < is really only applicable on files, its not that limiting an issue in Linux / Unix; if something isn't a file, you can easily make it look and act like one.

Argonauts
  • 735
8

It redirects the file after < to stdin of the program before <.

foo < bar

will run the program foo using the file bar as its stdin.

v7d8dpo4
  • 678
  • In some shells, it can also be written < bar foo to redirect the file bar into the stdin of program foo. – forquare May 16 '16 at 08:18