Bash – Why the Less-Than Sign Doesn’t Work as a Replacement for cat

bashcatio-redirectionshell

I heard about "useless use of cat" and found some suggestions, but the following outputs nothing in my bash shell.

< filename

Using cat works as expected though.

cat filename

I'm using Fedora Core 18 and GNU bash, version 4.2.45(1).

EDIT: Using it in front of a pipe doesn't work either.

< filename | grep pattern

Whereas using cat works as expected.

cat filename | grep pattern

EDIT2: To clarify, I know that I can use this

grep pattern < filename

but I read here https://stackoverflow.com/questions/11710552/useless-use-of-cat that I can also use it in front of the command. It does not work in front of the command though.

Best Answer

The less than and symbol (<) is opening the file up and attaching it to the standard input device handle of some application/program. But you haven't given the shell any application to attach the input to.

Example

These 2 examples do essentially the same thing but get their input in 2 slightly different manners.

opens file

$ cat blah.txt 
hi

opens STDIN

$ cat < blah.txt 
hi

Peeking behind the curtain

You can use strace to see what's going on.

When we read from a file

open("blah.txt", O_RDONLY)              = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=3, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(3, "", 65536)                      = 0
close(3)                                = 0
close(1)                                = 0

When we read from STDIN (identified as 0)

read(0, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(0, "", 65536)                      = 0
close(0)                                = 0
close(1)                                = 0

In the first example we can see that cat opened the file and read from it, blah.txt. In the second we can see that cat reads the contents of the file blah.txt via the STDIN file descriptor, identified as descriptor number 0.

read(0, "hi\n", 65536)                  = 3