3 ms·
Don't do this: cat file | wc -l => wc -l < file cat file | head -n 5 => head -n 5 file cat file | awk '{print $1}' => awk '{print $1}'
by lifthrasiir 3mo ago
Don't do this:
cat file | wc -l => wc -l < file
cat file | head -n 5 => head -n 5 file
cat file | awk '{print $1}' => awk '{print $1}' file
cat file | sort => sort file
Do this instead:
cat file | wc -l => <file wc -l
cat file | head -n 5 => <file head -n 5
cat file | awk '{print $1}' => <file awk '{print $1}'
cat file | sort => <file sort
The front-cat abuse is all about the order. The effective solution needs to keep the relative order of arguments.
- stouset 3mo agoOr just use cat and spend your brainpower on interesting, useful, and/or worthwhile topics. It boggles my mind that anyone cares about this.
- lifthrasiir 3mo agoProbably, but knowing that redirection operators can be freely moved within normal arguments [EDIT: thank ButlerianJihad for pursuing me to make this more accurate] is useful.
- ButlerianJihad 3mo agoThey are actually not “order-independent”, and their L-R parsing/processing is why constructs such as cat file > /dev/null 2>&1 work as intended.
- ablob 3mo agofunny enough, 2>&1 >/dev/null cat file appears to yield the same output. So i wonder where the not "order-independent" chimes in.
- ButlerianJihad 3mo agoYou're absolutely wrong! It does not yield the "same output", and here is why: if you cause your command to actually produce output on stderr (fd 2) it will appear as terminal output, because you have actually succeeded in "redirecting" stderr to wherever stdout (fd 1) was pointing initially.
- deleted 3mo ago[deleted]
- isityettime 3mo agoAll of this depends on your specific shell and its parser. Fish doesn't let you put redirections at the beginning like that (though I wish it did), while GNU Bash does.
- ButlerianJihad 3mo agofish is not POSIX-compatible, and not Bourne-compatible, so I don't see how that really matters at all. I used the rc shell from plan9 for quite a while, and I wouldn't expect its syntax rules to match, either!
- isityettime 3mo agoIt's worth noting because the redirections and their syntax are nonetheless otherwise shared. I don't think POSIX compatibility for shells is that important tbf. The heart of a Unix shell has little to do with POSIX syntax.
- ButlerianJihad 3mo agoI would say that if you can't use the same redirection syntax as Bourne/Bash, then the syntax rules aren't "shared". And that is because fish isn't POSIX-compliant. It's like when translating languages, some words are cognate, but some are "false friends" and while they look the same, they don't mean the same thing. So when using redirections in fish, the rules may be similar up to a point, but only up to a point.
- pdpi 3mo ago`2>&1` redirects FD2 to the current contents of FD1 (stdout), then `> /dev/null` redirects FD1 to /dev/null. That results in your errors going into stdout, and discarding regular output altogether: 0: stdin -> stdin -> stdin 1: stdout -> stdout -> /dev/null 2: stderr -> stdout -> stdout When you flip the order, `> /dev/null 2>&1` moves FD1 to /dev/null first, and then FD2 to the contents FD1 (/dev/null again), so you discard both errors and standard output: 0: stdin -> stdin -> stdin 1: stdout -> /dev/null -> /dev/null 2: stderr -> stderr -> /dev/null In your example, `cat file` is unlikely to produce any errors, which is why you're not seeing a difference.
- soraminazuki 3mo agoIf one needs brainpower to just use the redirection operator, it shows a likely lack of understanding of basic concepts in computing like processes and files. That should be concerning.
- ndsipa_pomu 3mo agoAnd yet you've visited these comments and cared enough to type out one yourself. I do agree that the performance cost of using "cat" is negligible, but sometimes it's instructive to learn techniques that improve efficiency. Personally, I write a lot of bash scripts and I tend to avoid using external programs when I can use built-ins e.g. "printf" instead of "echo", though avoiding "echo" is recommended anyway due to its lack of POSIX compliance.
- mkl 3mo agoThe order is the main thing, but it's not just that. It's common to swap cat with something else like head, tail, grep etc., and that's easy. If you have "< file command" instead of "cat file | command" you have to make edits in two places to insert the "|".