I'd like to send the contents of filename
to some_cmd
on the command line. What's the difference between running this:
$ cat filename | some_cmd
and
$ some_cmd < filename
Are there cases where I can or should use one and not the other?
I'd like to send the contents of filename
to some_cmd
on the command line. What's the difference between running this:
$ cat filename | some_cmd
and
$ some_cmd < filename
Are there cases where I can or should use one and not the other?
cat foo | somecmd
is running two programs—/bin/cat
, and somecmd
; and connecting the stdout of cat
to the stdin of somecmd
with a FIFO—which can be read only once, from start to back. That FIFO also doesn't expose metadata about the original file—neither its name nor its size can be discovered by somecmd
(without, for size, reading all the way to the end; this makes cat foo | tail
ridiculously slow for a multi-GB file).
somecmd <foo
is running only one program—somecmd
—connecting its stdin to a direct handle on the file foo
. It can thus copy that handle, rewind and reread it, hand out subsets of the file to different threads to process in parallel, map the file into memory for random access, etc.
Common programs like GNU sort
, wc -c
, tail
and shuf
can run much more efficiently when given a real, seekable file handle rather than a FIFO.
Always use redirection directly from a file rather than cat
'ing that file unless you have a specific and compelling reason to do otherwise.
As an example of such a compelling reason (where you might want to use cat
), consider the case where you need to stream a file only readable by a more-privileged user account.
sudo -u someuser /bin/cat -- /path/to/somefile | somecmd
...lets somecmd
run with your original, non-escalated privileges, so /etc/sudoers
can be configured to allow the original command to run only that single, specific cat
invocation.