When the shell gets a command line like: command > file.out
the shell itself opens (and maybe creates) the file named file.out
. The shell sets file descriptor 0 to the file file descriptor it got from the open. That's how I/O redirection works: every process knows about file descriptors 0, 1 and 2.
The hard part about this is how to open file.out
. Most of the time, you want file.out
opened for write at offset 0 (i.e. truncated) and this is what the shell did for you. It truncated .hgignore, opened it for write, dup'ed the filedescriptor to 0, then exec'ed head
. Instant file clobbering.
In bash shell, you do a set noclobber
to change this behavior.
In many shells including ksh
, zsh
and bash
, time
is a keyword and is used to time pipelines.
time foo | bar
Will time both the foo
and bar
commands (zsh
will show you the breakdown). It reports it on the shell's stderr.
time foo.sh > bar.txt
Will tell you the time needed to open bar.txt
and run foo.sh
.
If you want to redirect time
's output, you need to redirect stderr
in the context where time
is started like:
{ time foo.sh; } 2> bar.txt
This:
2> bar.txt time foo.sh
works as well but with ksh93
and bash
, because it's not in first position, time
is not recognised as a keyword, so the time
command is used instead (you'll probably notice the different output format, and it doesn't time pipelines).
Note that both would redirect both the output of time and the errors of foo.sh
to bar.txt
. If you only want the time output, you'd need:
{ time foo.sh 2>&3 3>&-; } 3>&2 2> bar.txt
Note that POSIX doesn't specify whether time
behaves as a keyword or builtin (whether it times pipelines or single commands). So to be portable (in case you want to use it in a sh
script which you want portable to different Unix-like systems), you should probably write it:
command time -p foo.sh 2> bar.txt
Note that you can't time functions or builtins or pipelines or redirect foo.sh
errors separately there unless you start a separate shell as in:
command time -p sh -c 'f() { blah; }; f | cat'
But that means the timing will also include the startup time of that extra sh
.
Best Answer
When your process (
find
) needs to actually write out the output, that obviously takes a lot longer than when you tell it to discard said output.When you use
find /
, both the stdout and stderr are sent to your terminal, and it has to write out both of them (i.e., the actual results and all the permission errors and whatnot)When you use
time find / >/dev/null
you are dropping the standard output of the command, but still printing out all the errors (if you have any). Judging by your results, you have lots of legitimate results and very few errors.When you use
time find / 2> /dev/null
, the standard output of the command is still being sent to your terminal, but now you're simply dropping the stderr. If you were finding through a filesystem that you did not have permission to read, this would actually be pretty fast.When you use
time find / > /dev/null 2>&1
, you are dropping the standard output, and then sending standard error to where standard output is being sent,... i.e., you are dropping both. This will not output anything, and thus will be the fastest of all commands.