I was playing around with the Apache php.ini
and got it so when I send emails with a PHP file that has the mail()
function it will save the email on my computer, which is good for testing and for web developers. This is the line of code I added in the php.ini
:
sendmail_path = "cat > /home/cam/Documents/TestEmails/`date '+%Y-%m-%d - %H-%M-%S'`.eml"
Also this line of code worked too:
sendmail_path = "tee > /home/cam/Documents/TestEmails/`date '+%Y-%m-%d - %H-%M-%S'`.eml"
What are the difference between the cat
and tee
commands?
Best Answer
cat
andtee
behave alike when you don't give them any filenames. That's what's happening in your example; the commands have output redirections (>
) but no actual command-line arguments. When you do pass thecat
andtee
commands filenames, they behave differently from one another, and you can even accidentally overwrite files and lose data by passing their names totee
when you meant to pass them tocat
.The reason
cat
andtee
do the same thing without any arguments, but different things with filenames passed as arguments, can be discerned by considering the behavior of each. In general, they have almost opposite behavior.cat
reads potentially many files and sends their output to one place, whiletee
reads one input and sends it to potentially many files.cat
cat
copies the content of all its input files to standard output, one after the other. This is to say that it concatenates the files. For example,cat x y
outputs the contents ofx
followed by the contents ofy
. When passed a single filename, it copies that file's contents to standard output and then, since it has no more arguments, stops.When you run
cat
with no filenames, it defaults to reading from its own standard input. Basically, that means it reads whatever is piped or redirected to it, or otherwise whatever is typed into a terminal. (Another way of putting this is that, with no filenames,cat
behaves likecat -
, sincecat
, like various other commands, treats-
specially and takes it to designate standard input.)tee
tee
copies the content of its standard input to all of its output files as well as its own standard output. This is to say that it functions like a T-junction--or, more precisely, N T-junctions where N is the number of output files whose names you pass to it. For example,tee x
reads its input, writes it to the filex
, and also writes it to its own standard output.tee x y
reads its input, writes it to the filex
and also to the filey
, and also writes it to its own standard output.The most common use of
tee
is to insert it into a pipeline with a single filename argument. For example, suppose you were piping the output of a command calledfoo
to the input of a command calledbar
. You could writefoo | bar
. But if you also wanted to log the output to a file calledlogfile
so you could inspect it, you could usefoo | tee logfile | bar
.tee
overwrites the files whose names you give it, unless you pass it the-a
option, in which case it appends to them. For example, to append to that log instead of overwriting it, you could usefoo | tee -a logfile | bar
.Unlike
cat
, thetee
command doesn't treat getting no filename arguments as a special case. Instead, simply writes its input to all zero of the files whose names you gave it, and then passes it along to its standard output as usual. The effect is that, as withcat
, runningtee
with no filenames also copies standard input to standard output.Culture favors cat when you just want to copy stdin to stdout.
While you can use either
cat
ortee
with no arguments for this purpose, if you usecat
then people will know what you mean.tee
without arguments is fine, but it looks like a mistake. Sometimes this is described by saying thatcat
is the idiomatic way to do it.Note also that the command-line options supported by
cat
andtee
are different. You would probably expect this, since they mostly do different things, and thus are capable of having their behavior customized in totally different way. Seeman cat
andman tee
for details, especially about this.