6

I by accident find a good way to filter useful lines of find: just pipe it to less and when it shows (END) at the bottom, press up arrow key and only correct lines are left. No Permission denied, no symbolic link errors, nothing else.

find / -name foo | less

But, why? Cannot find an answer about why this behaviour. less magically filters out non-result lines?

1
  • 2
    Now of course, find / -name foo 2>/dev/null does the same thing, but less is useful when the output is long. Well.
    – WesternGun
    Commented May 17, 2021 at 14:37

2 Answers 2

15

find with no “action” applies its default -print action, which outputs the full file name to standard output. Errors go to standard error.

The pipe operator only redirects standard output; so only “correct” file names are sent to less, everything else goes to standard error, which is your terminal. less also writes to your terminal, so you’ll initially see both file names and errors on your screen; but when you scroll up in less (or invoke any other action which causes it to update the screen), the errors will be overwritten by less’s updates since less is only aware of the input it’s seen from find’s standard output.

To page through the complete output in less, you need to redirect standard error too:

find / -name foo 2>&1 | less

To completely ignore errors, redirect it to the bit bucket instead:

find / -name foo 2>/dev/null | less
8
  • 1
    OK but I thought I see these "Permission denied" lines before pressing Up key. Do they belong to stderr?
    – WesternGun
    Commented May 17, 2021 at 11:36
  • 3
    Yes, find writes them to its standard error. less’s output is mixed up with that sent directly to your terminal, until it refreshes the screen (which happens when you scroll up). Commented May 17, 2021 at 11:36
  • 2
    I like to remember this by em-phasing the important part of the wordstderr: stderr as in, error :) just a tip in remembering it. @WesternGun Commented May 17, 2021 at 11:43
  • 2
    I think in bash you can simply say find / -name foo |& less. Commented May 18, 2021 at 14:11
  • 2
    @NordineLotfi, ...though that's a bit misleading, since stderr has more than just errors -- it also is the correct place for diagnostic output. Lots of things are "diagnostic" -- status logs, prompts to the user; really, anything that isn't part of the actual output a program is built to generate. Commented May 18, 2021 at 16:36
10

This has nothing to do with less itself. It's just that there are two output streams: standard output (stdout) and standard error (stderr). Error messages, as you would expect, go to stderr, while regular output goes to stdout. The pipe, by default, only captures stdout and ignores stderr. Since find's errors are in stderr, these are not sent to less and this is why it looks like less is filtering out the errors.

3
  • Ah yes. find / -name rime 2>null gives me the same output in terminal. Good. Now I don't know which answer to accept coz you are equally correct.
    – WesternGun
    Commented May 17, 2021 at 11:40
  • @WesternGun I would go for Stephen's, he gives a bit more detail. But it's completely up to you, whichever one you prefer. I can guarantee that neither Stephen nor I will take it personally :)
    – terdon
    Commented May 17, 2021 at 12:41
  • 2
    Thanks for being so generous. And correction to my comment: find / -name rime 2>/dev/null.
    – WesternGun
    Commented May 17, 2021 at 14:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .