When I pipe multiple unix commands such as grep, sed, tr etc. I tend to specify the input file that is being processed using cat. So something like cat file | grep ... | awk ... | sed ... .

But recently after a couple of comments left on my answers indicating that this was a useless use of cat, I thought I would ask the question here.

I looked up the issue and came across Wikipedia's article on UUOC and The Useless Use of Cat Award and it seems to me that the arguments made are from the perspective of efficiency.

The closest question I came across here was this one: Is it wasteful to call cat? – but it's not quite what I'm asking.

I guess what the UUOC camp suggest is to use cmd1 args < file | cmd2 args | cmd3 .. or if the command has an option to read from file then to pass in the file as an argument.

But to me cat file | cmd1 ... | cmd2 seems much easier to read and understand. I don't have to remember different ways of sending input files to different commands, and the process flows logically from left to right. First input, then the first process ... and so on.

Am I failing to understand what arguments are being made about the useless use of cat? I understand that if I'm running a cron job that runs every 2 seconds that does a lot of processing, then in that case cat might be wasteful. But otherwise what's the general consensus on the use of cat?

link|improve this question
I agree, here, the call to cat may be inefficient, but it makes the command much easier to understand and edit later, and (importantly, IMO) seperates each different command to having just one job, making the whole thing much easier to deal with. – Phoshi Aug 14 '11 at 18:20
feedback

4 Answers

up vote 4 down vote accepted

It's useless in the sense that using it like that doesn't accomplish anything the other, possibly more efficient options can't (i.e. producing proper results).

But cat is way more powerful than just cat somefile. Consult man cat or read what I wrote in this answer. But if you absolutely positively only need the contents of a single file, you might get some performance advantage from not using cat to get at the file contents.

Regarding readability, this depends on your personal tastes. I like cating files into other commands for the same reason, especially if the performance aspects are negligible.

It also depends on what you're scripting. If it's your own shell and convenience methods for your desktop machine, nobody except you will care. If you stumble upon a case where the next tool in the chain would be better off being able to seek, and distribute this as a frequently used piece of software on some minimal Linux system on a low-performance router or similar device with real limits on processing ability, that's different. It always depends on the context.

link|improve this answer
feedback

I think the position being taken by some of those commenting on something being a UUOC is that if one really understands Unix and shell syntax, one would not use cat in that context. It's seen as like using poor grammar: I can write a sentence using poor grammar and still get my point across, but I also demonstrate my poor understanding of the language and by extension, my poor education. So saying that something is a UUOC is another way of saying someone doesn't understand what they're doing.

As far as efficiency goes, if you are executing a pipeline from the command line, it takes less time for the machine to execute cat somefile | than it does for you to think about whether it might be more efficient to use < somefile. It just doesn't matter.

link|improve this answer
feedback

In every day command line use it's not really much different. You especially aren't going to notice any speed difference since the time on CPU avoided by not using cat, your CPU is just going to be idle. Even if you're looping through hundreds or thousands (or even hundreds of thousands) of items in all practicality it's not going to make much difference, unless you're on a very loaded system (Load Average / N CPU > 1).

The where the rubber meets the road is about forming good habits and discouraging bad ones. To drag out a moldy cliché, the devil is in the details. And it's details like this that separate the mediocre from the great.

It's like while driving a car, why make a left turn when you can just make three rights instead? Of course you can, and it works perfectly. But if you understood the power of left turns then three rights just seems silly.

It's not about saving one file handle, 17k of RAM and 0.004 seconds of CPU time. It's about the entire philosophy of using UNIX. The "power of left turns" in my illustration isn't merely redirecting input, it's the UNIX philosophy. Fully grokking this will make you excel far better than those around you, and you will garner respect from those who do understand.

link|improve this answer
feedback

What would be really nice is a shell that supports syntax like:

< filename cmd | cmd2 cmd2arg1... | cmd3

In the meantime, I think cat filename | realcmd1... is acceptable, as it keeps the syntax standardised with initial commands that require the filename as an argument.

link|improve this answer
6  
Bash and similar shells support < filename cmd | cmd2 .... Is that close enough? – garyjohn Aug 14 '11 at 19:18
@garyjohn: I think you should post that as an answer. – Kevin Reid Aug 14 '11 at 19:41
Ahh, I didn't know that garyjohn. It's exactly what I meant actually (fixed), but I didn't know it was implemented :) – Lee Aug 14 '11 at 20:29
2  
Obligatory old shell-hacker comment: Bourne-style shells have supported the < file command ... since at least the mid-80s and probably as far back as the 70s when the original sh was written. More generally, i/o redirections are parsed left to right, and can be interspersed in any order within the command line. So, cmd <file arg arg... would also be valid. – Dale Hagglund Aug 15 '11 at 2:28
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.