Admittedly its taken me a long time to remember that the file is the last argument to grep, when so many other commands its the first. I'd guess common abuse is due to being easier to type cat x | than to dig up the man page
Presumably written by someone without much interactive shell experience.
When you're building a pipeline, putting cat first can often be quite convenient. Essentially, it's more composable: it defines the input to the pipeline without committing to a specific tool. For example, you can up-arrow in the shell and change the part after the pipe without having to skip back past the filename.
In fact if you don't start with cat, it's possible you're more of a script kiddie than a software developer.
I raised eyebrows recently when I was working with someone and we needed to create a file and instead of starting an editor I did:
cat > filename
...
Ctrl-D
if this wanton abuse of cat(1) doesn't stop, we're on track to run out of PIDs by 2031! Just because Unix makes it cheap and easy to fork doesn't mean you have to!
Unless you're executing these commands in a loop over a large number of items, or the item itself is gargantuan, it's almost always harmless.
Personally, when I'm exploring, I build a command line iteratively. Cat the file to see the content, pipe to grep to get the lines I want, sed/awk/cut/etc to finagle from there.
The beauty of cat is that streams are the universal interface.
Program A might accept a file as the last positional arg. Program B might accept it as a named arg, where the name/flag could be anything from --input or -f or --file etc.
But a program will read from STDIN, which all good unix programs do, then piping cat into it works every time. I can write the cat foo.txt part before I even know what command I'm piping it into.
For interactive use like these examples I think this is terrible advice. cat is very helpful because it fits into pipelines like every other command. For example:
Take a look at the start of a file:
head file
Filter for things:
head file | grep ...
Reformat, remove unwanted stuff, etc.:
head file | grep ... | sed ...
Do things or dry run echo based on each line:
head file | grep ... | sed ... | while read a; do ...; done
It all looks good so we change head to cat to run it on the whole file:
cat file | grep ... | sed ... | while read a; do... ; done
Yes you can technically change "head file |" to "< file" but why bother? That's changes in two places and navigating between them instead of just <alt-d> cat.
Same is true for other workflows. E.g. if you start with one of these supposedly better commands like "wc -l < file" (why isn't that just "wc -l file"?):
wc -l < file
Oh wait, we don't want every line, just ones matching a pattern. We could change it to
wc -l <(grep ... file)
or
grep -c ... file
which are both more work than just adding to an existing cat-based pipeline, where we just replace cat with "grep ...":
grep ... file | wc -l
If we need to also match another pattern or whatever this pipeline approach is better then too.
First off, stop using cat, use something modern. I recommend redpanda, rp, but I'm biased since I'm the author.
Anyway, the reason I use useless cat is because when I'm working with large files, it starts with head, not cat, or tail, and then only after I've built the pipeline do I use cat to process the whole file.
19 comments of 57
[ 0.22 ms ] story [ 15.2 ms ] threadhttp://catb.org/jargon/html/U/UUOC.html
Admittedly its taken me a long time to remember that the file is the last argument to grep, when so many other commands its the first. I'd guess common abuse is due to being easier to type cat x | than to dig up the man page
Now for firefox:
Maybe people should be looking at that ? I will not even get into modern Linux Desktops :)When you're building a pipeline, putting cat first can often be quite convenient. Essentially, it's more composable: it defines the input to the pipeline without committing to a specific tool. For example, you can up-arrow in the shell and change the part after the pipe without having to skip back past the filename.
In fact if you don't start with cat, it's possible you're more of a script kiddie than a software developer.
< file grep abc
Chrome probably spawned two processes when I cmd+clicked this into a new tab. It really doesn't matter.
- various HostGator employees, c. 2011
(who gives even a single shit, my god)
Personally, when I'm exploring, I build a command line iteratively. Cat the file to see the content, pipe to grep to get the lines I want, sed/awk/cut/etc to finagle from there.
Program A might accept a file as the last positional arg. Program B might accept it as a named arg, where the name/flag could be anything from --input or -f or --file etc.
But a program will read from STDIN, which all good unix programs do, then piping cat into it works every time. I can write the cat foo.txt part before I even know what command I'm piping it into.
Take a look at the start of a file:
Filter for things: Reformat, remove unwanted stuff, etc.: Do things or dry run echo based on each line: It all looks good so we change head to cat to run it on the whole file: Yes you can technically change "head file |" to "< file" but why bother? That's changes in two places and navigating between them instead of just <alt-d> cat.Same is true for other workflows. E.g. if you start with one of these supposedly better commands like "wc -l < file" (why isn't that just "wc -l file"?):
Oh wait, we don't want every line, just ones matching a pattern. We could change it to or which are both more work than just adding to an existing cat-based pipeline, where we just replace cat with "grep ...": If we need to also match another pattern or whatever this pipeline approach is better then too.Anyway, the reason I use useless cat is because when I'm working with large files, it starts with head, not cat, or tail, and then only after I've built the pipeline do I use cat to process the whole file.