Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cat file | ... vs ... <file

Is there a case of ... or context where cat file | ... behaves differently than ... <file?

like image 403
namin Avatar asked Mar 31 '10 11:03

namin


People also ask

What is the difference between cat file and cat file?

In the first case, cat gets told to open the file itself, while in the second case the shell opens it, and cat doesn't know anything except that there's a stream of data coming in through its standard input, that it is supposed to print. There is no piping involved with cat < file1. txt .

What does it mean to cat a file?

The cat (short for “concatenate“) command is one of the most frequently used commands in Linux/Unix-like operating systems. cat command allows us to create single or multiple files, view content of a file, concatenate files and redirect output in terminal or files.

Does cat create a file?

The cat command is a very popular and versatile command in the 'nix ecosystem. There are 4 common usages of the cat command. It can display a file, concatenate (combine) multiple files, echo text, and it can be used to create a new file.

How do I cat output to a file?

To create a new file, use the cat command followed by the redirection operator ( > ) and the name of the file you want to create. Press Enter , type the text and once you are done, press the CRTL+D to save the file. If a file named file1. txt is present, it will be overwritten.


7 Answers

When reading from a regular file, cat is in charge of reading the data, performs it as it pleases, and might constrain it in the way it writes it to the pipeline. Obviously, the contents themselves are preserved, but anything else could be tainted. For example: block size and data arrival timing. Additionally, the pipe in itself isn't always neutral: it serves as an additional buffer between the input and ....

Quick and easy way to make the block size issue apparent:

$ cat large-file | pv >/dev/null
5,44GB 0:00:14 [ 393MB/s] [              <=>                                  ]
$ pv <large-file >/dev/null
5,44GB 0:00:03 [1,72GB/s] [=================================>] 100%
like image 166
JB. Avatar answered Sep 30 '22 06:09

JB.


Besides the thing posted by other users, when using input redirection from a file, standard input is the file but when piping the output of cat to the input, standard input is a stream with the contents of the file. When standard input is the file will be able to seek within the file but the pipe will not allow it. You can see this by finding a zip file and running the following commands:

zipinfo /dev/stdin < thezipfile.zip

and

cat thezipfile.zip | zipinfo /dev/stdin

The first command will show the contents of the zipfile while the second will show an error, though it is a misleading error because zipinfo does not check the result of the seek call and errors later on.

like image 43
Geoff Reedy Avatar answered Sep 30 '22 05:09

Geoff Reedy


A useless use of cat is always to be avoided. It's like driving with the handbrake on. It wastes CPU cycles for nothing, the OS constantly context switching between the cat process and the next in the pipe. If all the world's useless cats were gone and stopped being invented, reinvented, passed on from father to son, we wouldn't have global warming because we could easily live with 1.21 Gigawatts of power saved.

Thanks. I feel better now. Please join me in my crusade to stamp out useless use of cat on stackoverflow. This site is, as far as I perceive it, a major contribution to the proliferation of useless cats. I don't blame the newbies, but I do want to teach them. Workers and newbies of the world, loosen the handbrakes and save the planet!!!1!

like image 35
Jens Avatar answered Sep 30 '22 06:09

Jens


cat will allow you to pipe multiple files in sequentially. Otherwise, < redirection and cat file | produce the same side effects.

like image 31
spoulson Avatar answered Sep 30 '22 05:09

spoulson


Pipes cause a subshell to be invoked for the command on the right. This interferes with environment variables.

cat foo | while read line
do
  ...
done
echo "$line"

versus

while read line
do
  ...
done < foo
echo "$line"
like image 38
Ignacio Vazquez-Abrams Avatar answered Sep 30 '22 06:09

Ignacio Vazquez-Abrams


One further difference is behavior on a blocking open() of the input file.

For example, assuming input is a FIFO with no writers, one invocation will not spawn any child programs until the input file is opened, while the other will spawn two processes:

prog ... < a_fifo      # 'prog' not launched until shell can open file
cat a_fifo | prog ...  # 'prog' and 'cat' are running (latter may block on open)

In practice this rarely matters except in contrived circumstances. prog might periodically log or do some cleanup work while waiting for input, for example, which you might want to happen even if no input is available. (Why wouldn't prog be sophisticated enough to open its own input fifo nonblocking?)

like image 45
pilcrow Avatar answered Sep 30 '22 06:09

pilcrow


cat file | starts up another program (cat) that doesn't have to start in the second case. It also makes it more confusing if you want to use "here documents". But it should behave the same.

like image 39
Paul Tomblin Avatar answered Sep 30 '22 05:09

Paul Tomblin