Understanding grep and pipes in linux

argumentsfilesgreppipe

I came across this post which explains my problem.
Suppose there is a file called file.txt which contains "foo World".
The answer posted by Tyler explains a lot however I am confused as to how

cat file.txt | grep "foo"

is similar to

grep "foo" file.txt

I thought grep required the following

grep input argument  // input is the string to search for (i.e) foo and
                     //  argument is the file path (./file.txt)

Now the output of cat file.txt is content of the file which is foo World this becomes the input of the grep? Am I correct? If so I thought grep required a filepath as a string?

Best Answer

Most commands can deal with input that's either a file that they need to open for input, or as a stream of data that's passed to the command via STDIN.

When the contents of cat file.txt is sent to another command through a pipe (|) the output via STDOUT that's passed to the pipe on the left side, is setup and fed to the command that's on the right side of the pipe's STDIN.

If the contents is not being passed via STDOUT -> STDIN via a pipe, then commands can receive data by opening files that are passed by name via command line arguments.

Examples

Sends output to STDOUT.

$ cat file 
1
2
3
4
5

Output from cat file is sent via STDOUT to grep's STDIN via the pipe.

$ cat file | grep 5
5

Processing the file as a command line argument.

$ grep 5 file 
5

Processing the contents of the file via STDIN directly.

$ grep 5 < <(cat file)
5

Here I'm demonstrating that the contents of file can be directed to grep via STDIN above.

Related Question