How do I redirect output from "find", either to a file or another command?

I'm trying to find out what happened to the rogue game that apt-get told me it installed, so I thought I would find the file. I went to the root and entered:

find -name "rog*.*"

I get a large number of lines saying my access is denied in various directories. I figure I'll practice my Unix commands by using grep to filter out these lines, so I enter:

find -name "rog*.*" | grep -v denied

Attempting to filter out all the lines in the 'find' output that have 'denied' in them. This doesn't work. I try

find -name 'rog*.*' > ~/output.txt

on the theory that, after the output gets into the file, I can filter it from there. But it still puts the output on the screen, and creates and empty file.

I'll go try to find my rogue installation another way, but would like to know how to use "find" this way as it's fairly commonly used. What am I doing wrong with it.

I searched for examples, but all the ones I found use "exec", and I didn't want to start down a rabbit warren of other ways to do things. If I find out this is just impossible, that find doesn't work the way other unix commands used to work, then I guess I'll have to.

1 Like

The error msgs usually get redirected to steer. By mapping stderr (2) to stdout (1), you get to do whatever you want...

find -name "rog*.*" 2>&1 | grep -v denied

This looks more or less like what I need, but I need some help parsing it. When I try to execute the command in the root directory, it says I don't have access, which is fair.

I think of the ">" symbol as "redirect output to a file, I'll tell you what the filename is". I think of "|" as "take this output and feed it into another program", which doesn't require a filename. I can tell that "2" and "1" represent stdout and stderr; is there a way to direct them both to the pipe, instead of the file? AFAIK, I/we don't have to first direct output to a file and then to grep, and in fact I don't know that it will work that way.

2>&1 is an operator which duplicates file descriptors, in this case stderr (2) is duplicated onto stdout (1) (See the Duplicating File Descriptors in the bash manual)

In

 command1 2>&1 | command2

the combined stderr and stdout from command1 will be piped as stdin to command2

Hmmm. When I enter

find -name "rog*.*" 2&>1 | grep -v denied

from the root directory, it responds with

bash: 1: Permission denied

. Is there some reason I would need write permissions on root to execute this?

1 Like

Certainly not. More context please, like the full script and a listing of the directory where this happens.

So you duplicate stderr from stdout to just suppress the error messages, then? Why not redirect stderr to /dev/null in the first place?

There is no script. I am entering this command on the command line.

I'm not just "suppressing the error messages"; I am glad to be reminded about /dev/null, but what I'm trying to do here is understand how to use find in this way -- if it outputs things that I can filter with grep, then how do I pipe the output to the grep command?

I don't know what the contents of the root folder have to do with anything; it hasn't changed since I installed the Raspberry Debian yesterday. In case you can make some use of it, here it is:

total 72
drwxr-xr-x   2 root root  4096 Feb  5 10:52 bin
drwxr-xr-x   3 root root  3584 Dec 31  1969 boot
drwxr-xr-x  16 root root  3780 Feb  9 11:33 dev
drwxr-xr-x 118 root root  4096 Feb  9 11:19 etc
drwxr-xr-x   3 root root  4096 Feb  5 10:47 home
drwxr-xr-x  17 root root  4096 Feb  5 11:00 lib
drwx------   2 root root 16384 Feb  5 11:22 lost+found
drwxr-xr-x   3 root root  4096 Feb  8 21:46 media
drwxr-xr-x   2 root root  4096 Feb  5 10:42 mnt
drwxr-xr-x   6 root root  4096 Feb  5 10:58 opt
dr-xr-xr-x 152 root root     0 Dec 31  1969 proc
drwx------   4 root root  4096 Feb  5 11:24 root
drwxr-xr-x  25 root root   760 Feb  8 23:28 run
drwxr-xr-x   2 root root  4096 Feb  8 19:16 sbin
drwxr-xr-x   2 root root  4096 Feb  5 10:42 srv
dr-xr-xr-x  12 root root     0 Feb  9 12:09 sys
drwxrwxrwt  13 root root  4096 Feb  9 16:17 tmp
drwxr-xr-x  11 root root  4096 Feb  5 10:53 usr
drwxr-xr-x  12 root root  4096 Feb  9 11:17 var

I know my process does not have write privilege on the folder, I didn't think I would need it, and evidently you don't either.

So my question is -- if this is the correct command, then why am I being told "Permission denied" when I run it?

2&>1 creates a file named 1 in the current directory.
2>&1 is correct: it redirects descriptor 2 (stderr) to descriptor 1 (stdout). The & makes the following a file descriptor.
And the following | passes the now combined stdout to the following command as stdin.

2 Likes

Oops, typo in my earlier reply - thanks MadeInGermany for picking this up.

Thanks, perhaps I should have realized it was something like that. If you (MadeInGermany) would care to clarify one more thing: you say "The & makes the following a file descriptor" -- what does "file descriptor" mean in this context?

There is nothing stopping you creating file descriptors and use them afterwards
like

[some program] -options -args >&6 # as I need the output to use as input for &4 that.....

Well, that's interesting. I see from searching for "File Descriptor" that it refers to an integer that in turn refers to a 'file' (or a byte stream) for a process on a Unix system. I guess the only other thing I would like to know now is how to know whether the "&" is needed at a particular point on the command line. As we have it "2" indicated stderr, but "1" indicated a file named 1, and "&1" indicated stdout. How would I know when to include "&"?

OK I see we could have some misunderstanding: I suggest you document yourself on special files, file descriptors, and what I mentionned above related to named pipes... In order to understand what I thrown at you ( thus know how to create them...) I suppose a little reading on what and how to use FIFOs may be far from beeing a waste of time...

Looking at the thread title, we are going of topic...
So reading again #1

Normal if you are not root... many files are only readonly for that user

find -name "rog*.*"

should really be:

find  <the pathto where to begin your search> -name "rog*.*"

doing so if you installed ( not root) you sure will see what you are looking for
...

find -name 'rog*.*' > ~/output.txt

Should not :

What have you not said to us?

find -name "rog*.*" | grep -v denied

Sure will send to your Display, you have not redirected to a file
Remember STDOUT? yes the default is your display...

find -name "rog*.*" | grep -v denied > ~/mysearch.out

would have not displayed anything...

Well, on the right side of > and < there can be a filename, so the & prefix indicates it is a file descriptor.
On the left side it is clear that it's a file descriptor, so the bare number does it.
Note that > is identical with 1> and < is identical with 0< .