I want my bash to print 'found' only if something is found, using the find command. But using && does not help: even if found nothing, I'm getting 'found' printed. Example:
$ pwd
/data/data/com.termux/files/home/test/test1/test4
$ ls
xaa xab
$ find . -name xac && echo 'found'
found
$ find . -name xaa && echo 'found'
./xaa
found
You can make
find
itself printfound
:The
-quit
will makefind
quit after the first match, sofound
is only printed at most once.On a similar thread on Unix & Linux (make find fail when nothing was found), I used
grep -qz
to return a non-zero exit status iffind
found nothing:Which you can use to construct compound commands using
&&
orif
:muru's answer is appropriate and well suited for cases where we want to print something if file is found. For general case when we want to execute external command, such as
echo
, we could use-exec
flag.The
{}
part passes filename to the command between-exec
and\;
as arguments. Note the\
before;
- it prevents shell from misinterpreting it; in shell closing semicolon signifies end of command, but when escaped with slash , shell will treat it as literall text to be passed tofind
command and to find command it serves as closing-exec
flag's arguments.For constructing conditionals of the
if found do this; else do that
sort, we could make use of command substition$()
andtest
command ( aka[
):Addressing Dan's comment
Dan in the comments asked:
Let's understand the problem first. Usually, in shells there's concept of word-splitting, which means unquoted variables and positional parameters will be expanded and treated as separate items. For instance, if you have variable
var
and it containshello world
text, when you dotouch $var
the shell will break it down into two separate itemshello
andworld
andtouch
will understand that as if you were trying to create 2 separate files; if you dotouch "$var"
, then shell will treathello world
as one unit, andtouch
will create one file only. This is important to understand that this happens only due to how shells work.By contrast,
find
doesn't suffer from such behavior, because commands are processed byfind
itself and executed byexecvp()
system call, so there's no shell involved. While curly braces do have special meaning in shells, because they appear in the middle offind
command, and not in the beginning, they carry no special meaning to shell in this case. Here's an example. Let's create a few difficult filenames and try to pass them as argument tostat
command.As you can see,
stat
receives difficult filenames perfectly fine withfind
, which is one of the main reasons why it is recommended for usage in portable scripts, and especially useful when you're traversing directory tree and want to do something with filenames that might potentially have special characters in them. Therefore, it is not necessary to quote curly braces for commands executed infind
.It is a different story when shell gets involved. Sometimes you need to use a shell to process filename. In that case, quoting will indeed matter, but it's important to realize that it's not find's problem - it is the shell that does word splitting.
So when we quote within shell, it will work. But again, that's important for shell, not
find
.