While the nice answer of choroba cures your problem, the reason for the behavior you have noticed is the default pipeline behavior in bash (and i suppose in most of the shells as well).
As described in
man bash pipelines section:
The standard output of command is connected via a pipe to the standard
input of command2. This connection is performed
before any redirections specified by the command (see REDIRECTION below).
command1 is not by default fed to
command2 through the pipe but is driven to your tty, the default stderr link.
Bash manual also says:
If |& is used, command's standard error, in addition to its standard output, is connected to command2's standard input through the pipe; it is shorthand for 2>&1 |.
So in your case, if you want to pipe to grep command, the find command errors which by default are sent to
/dev/stderr you need to use one of these two forms:
find / |& fgrep somestuff.ext
find / 2>&1 | fgrep somestuff.ext
Your queston could be also titled like "Why stderr is ignored by pipes".
And the answer is because this is how bash and linux are made by default; to treat
stdout differently than
stderr, in order user to be capable to log/treat those two outputs differently.
For example you can pipe
stdout of command1 to
stdin of command2 and on the same time you can send
stderr of command1 to a log file using
Actually when you run a command without any redirections specified like
It is equivallent to
find / 1>/dev/stdout 2>/dev/stderr
Which is finally resolved to:
find / 1>/dev/tty1 2>/dev/tty1 #assuming that you are logged in tty1
as can be verified by a single
ls -all /dev/st*
lrwxrwxrwx 1 root root 15 Nov 25 15:36 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Nov 25 15:36 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Nov 25 15:36 /dev/stdout -> /proc/self/fd/1
ls -all /proc/self/fd/2
lrwx------ 1 root root 64 Nov 28 02:46 /proc/self/fd/2 -> /dev/tty1
ls -all /proc/self/fd/1
lrwx------ 1 root root 64 Nov 28 02:46 /proc/self/fd/1 -> /dev/tty1
If for any reason you want to "join"
stderr of a command, then you need to explicitly declare your purposes to
|& (for pipelines) or
2>&1 (for any kind of output redirection)