0

In my previous question In find -exec, how to substitue current file by {}?, I have asked about test with find. I want to find all files I do not own. So there is proper find command:

find . -type f ! -user "$USER"

but so should be this one as well:

find . -type f -exec bash -c '
    for pathname do
        [[ ! -O "$pathname" ]] && printf "%s\n" "$pathname"
    done' bash {} +

yet both gives different results .

1) if I do [command one] | wc -c --> 4121

But: [command two] | wc -c --> 236768 (PS: I am searching files in my $HOME).

Both gives different numbers of how many files they found.

2) Both still give in result files, that are directories (yes, directories I do not own and thus - permission denied). They give directories despite having find . -type f type files (not dirs) in argument of option, why? (When I ls -ld one of those directory, none is link or anything else)

6
  • Are you running either of these commands with sudo? You would definitely get "Permission denied" errors when find tries to enter directories not owned by you that you don't have access to. This is most likely why these errors occur. Have you looked at the output (not errors) to try to figure out what the differences in result are?
    – Kusalananda
    Apr 13 '20 at 18:41
  • 1) no sudo. That is the point, I am trying to look up only those files I own. I get permission denied after wc (or I only see it after wc, but the error could arise before pipe by find) 2) No I did not look at results, there is many files, that would take a lot of time to compare, neither does diff work, because that would be the other way - big output. Is there any program for that? Anyway, why it is showing directories, when specified type f?
    – Herdsman
    Apr 13 '20 at 18:50
  • It is not clear if "showing directories" means that the error messages mention directories, or if the find results mention directories. If you have directories that you don't have access to, I would expect these to show up in error messages. As for comparing, just sort the output and use diff.
    – Kusalananda
    Apr 13 '20 at 19:00
  • 1
    @Herdsman You're right about the origin of that error -- find is trying to explore that directory to find files, and getting that error as a result. As for the differences in files listed: rather than trying to catalog them all, I'd just look at the first few differences, and try to figure out why they're different. Apr 13 '20 at 19:16
  • 1
    Why are you running wc -c? That will count characters, not lines. So it doesn't help you know how many results you got, only how those results were reported. I doubt this is the issue, it just seems strange to use -c here.
    – terdon
    Apr 13 '20 at 19:20
0

To avoid having find enter directories that are not actually accessible to you, you can use ! -executable -prune:

find . ! -executable -prune -type f ! -user "$USER"

The negated -executable test will be true for directories that you don't have access to, and -prune will remove these from find's search tree, stopping the utility from trying to access them, and thus avoiding generating permission errors.

The -executable test (as well as the analogous -readable and -writable tests) are non-standard and require GNU find.

I can't (yet) say anything about the differences in result as you have said nothing about these. Since the output varies so drastically in size, it ought to be trivial to find and examine cases where one command found something that the other command did not find.

1

Hmm ..., in my homedir, both commands work the same. 8-/

Nevertheless, you should redirect the stderr to /dev/null and use wc -l to correctly count the output.

find . -type f ! -user "$USER" 2>/dev/null | wc -l
find . -type f -exec bash -c '
    for pathname do
        [[ ! -O "$pathname" ]] && printf "%s\n" "$pathname"
    done' 2>/dev/null bash {} + | wc -l

From here you could redirect the results to text files and compare the files to look for differences.

find . -type f ! -user "$USER" 2>/dev/null > /tmp/file_1.txt
find . -type f -exec bash -c '
    for pathname do
        [[ ! -O "$pathname" ]] && printf "%s\n" "$pathname"
    done' 2>/dev/null bash {} + >/tmp/file_2.txt
diff /tmp/file_{1,2}.txt

If there are differences, take some of the excess files of /tmp/file_2.txt and investigate further why the file is not considered ' True if file exists and is owned by the effective user id'.

4
  • It looks like you are trying to redirect the output of the bash -c script, but since the placing of the redirection doesn't really matter (redirections are parsed separately) you are actually redirecting the output of find, not the bash -c script. This happens to be what I think you want to do though.
    – Kusalananda
    Apr 13 '20 at 19:28
  • Now you got me thinking again. I wanted to redirect the stderr of find as find is most likely throwing the 'permission denied' message. I just got the bash {} +mixed up in it. Nevertheless, I curious to see where the additional 232600 characters are coming from. ;-)
    – bey0nd
    Apr 13 '20 at 19:39
  • In a now deleted self-answer, they indicate that the lower of the numbers is in fact coming from wc -l.
    – Kusalananda
    Apr 13 '20 at 19:40
  • 236768 characters divided by 4121 lines ~ 57 char/line. That sounds reasonable.
    – bey0nd
    Apr 13 '20 at 19:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.