I occasionally see things like:
cat file | wc | cat > file2
Why do this?
When will the results (or performance) differ (favourably) from simply:
cat file | wc > file2
I occasionally see things like:
cat file | wc | cat > file2
Why do this?
When will the results (or performance) differ (favourably) from simply:
cat file | wc > file2
Both of those examples are useless uses of cat. Both are equivalent to wc < file1 > file2. There is no reason to use cat in this example, unless you are using cat file as a temporary stand-in for something that dynamically generates output.
cat file | wc | cat > file2
would usually be two useless uses of cat as that's functionally equivalent to:
< file wc > file2
However, there may be a case for:
cat file | wc -c
over
< file wc -c
That is to disable the optimisation that many wc implementations do for regular files.
For regular files, the number of bytes in the file can be obtained without having to read the whole content of the file, but just doing a stat() system call on it and retrieve the size as stored in the inode.
Now, one may want the file to be read for instance because:
the stat() information cannot be trusted (like for some files in /proc or /sys on Linux):
$ < /sys/class/net/lo/mtu wc -c
4096
$ cat /sys/class/net/lo/mtu | wc -c
6
Of course, those are exceptions. In the general case, you'd rather use < file wc -c for performance reasons.
Now, you can imagine even more far fetched scenarios where one may want to use: cat file | wc | cat > file2:
wc has an apparmor profile or other security mechanism that prohibits it from reading or writing to files while it's allowed for cat (that would be unheard of)cat is able to deal with large (as in > 232 bytes) files, but not wc on that system (things like that have been needed for some commands on some systems in the past).wc (and the first cat) to run and read the whole file (and be killed at the very last minute) even if file2 can't be open for writing.file. Though wc < file > file2 || : would make more sense.lsof (list open files)) the fact that he's getting a word count from file or that he's storing a word count in file2.While I don't disagree with the argument for saying it is a 'useless use of cat', there can be reasons for it:
In many languages (including English) words and sentences are read from left to right, so showing the flow of data in the same way can appear more natural to the reader.
A reason for the second cat could be to mask the return code. Such as:
$ wc < /etc/passw
sh: /etc/passw: Cannot find or open the file.
$ echo $?
1
Whereas with cat:
$ wc < /etc/passw | cat
sh: /etc/passw: Cannot find or open the file.
$ echo $?
0
This can come into play if the shell has set -e set. In the first example, this would abort the shell after wc whereas in the latter example it would continue on. Obviously there are other ways of dealing with this.
Also, the performance difference of the two statements (ie with or without cat) is negligible (esp. on today's machines) and if it was important, shell is the wrong language to use.
Let's suppose prog forks a new subprocess and exits, and the new subprocess writes something to its standard output and then exits.
Then the command
prog
won't wait for the subprocess to exit, and it will display the shell prompt early. But the command
prog | cat
will wait for an EOF on the stdin of cat, which effectively waits for the subprocess to exit. So this is a useful use of cat.
The statement contains two uses of cat.
cat file | wc | cat > file2
Clearly the 2nd cat is of no value, as
cat file | wc > file2
has the same meaning in all shells I have ever used.
However
< file wc > file2
does not work in all shells.
Not everyone is using a modem shell on a modem version of unix. (It can be off benefit to write pipeline in a way that work on all systems that have the commands in the pipe installed, even if some of these commons don't ship as standard with the given OS.)