1

How can I use the result of a find command in an if statement and compare with true or false?

Something like this:

if [ `find . -name test.txt -size 156c`="true" ]; then echo Found; fi

This is the whole script:

#!/bin/bash
if [ $# -ne 2 ]
then
    echo Not enough params
fi

if [ `find . -name $1 -size $2c | grep -q .` -eq 0 ]
then
    echo OK
fi  
2
  • 1
    As a side remark, I would recommend quoting any variable names as you are expanding them, e.g. "$1", "$2"c; otherwise the script will break if any of its parameters contain white space. Commented Mar 25, 2015 at 15:46
  • You give a vague statement of an objective, and a command that you know doesn't work. This would be a better question if you stated your objective clearly. I guess it is something like "I want to use the find command to test a single file to see whether it satisfies a find test, such as size = some specified number." Commented Mar 26, 2015 at 5:59

3 Answers 3

3

Perhaps simply piping the output of find into grep would do the trick:

if find . -name test.txt -size 156c | grep -q .; then echo Found; fi

The call to find will have no output unless a file matching the name and size conditions you set is found, and grep . will have exit status 0 ("true") only if its input is non-empty. Option -q asks to not print any output, which would be irrelevant here because we only care about the exit status.


To clear another possible source of confusion: as @derobert mentioned in a comment, the brackets are not part of the syntax of the if construct at all: you will find that there exists a command named [, which has the job of evaluating boolean expression, and returning their truth value in the form of an exit code ([ can also be a shell built-in); it is this command that checks for the presence of a closing bracket:

$ [ 3 -gt 2 ] ; echo $?
0

$ [ 3 -lt 2 ] ; echo $?
1

$ [ 3 -lt 2 ; echo $?
bash: [: missing `]'
2

In the commands above, 0 means true, 1 means false, and 2 signals an error.

11
  • I tried if [ find . -name test.txt -size 156c | grep -q . -eq 0 ]; then echo Found; fi but it doesn't work. Commented Mar 25, 2015 at 14:56
  • 1
    Then try the actual code that I posted. You don't need any brackets. Commented Mar 25, 2015 at 14:57
  • It gives me an error on that line: " line 8: [: missing `]' " if i don't use brackets Commented Mar 25, 2015 at 14:59
  • Does the line, typed alone work? If so, the error you get comes from some other part of your script. Commented Mar 25, 2015 at 15:01
  • 1
    I've seen your edit. If you replace line 8 with the code I posted in my answer (up to, but not including, the first ;), then there is no way you will get an error message mentioning [, because that line will not contain a bracket. Commented Mar 25, 2015 at 15:32
0

As I stated in my comment, I assume that your question is actually

How do I use the find command to test a single file to see whether it satisfies a find test, such as size = some specified number?

where the name of the file is specified as a parameter to a script (and thus is not known to you in advance).  You’re building up an answer around the command

if find . -name "$1" -size "$2"c | grep -q .
then
    echo OK
fi

I’ve taken the liberty of inserting the quotes that dhag recommended.  This is not a bad start, but it has some problems:

  1. If the user runs the script with a parameter of test.txt, and there is a file called test.txt in a subdirectory of the current directory, then find will find it and print its pathname, and so the grep will succeed.  But, if your script is trying to do something with a file called test.txt in the current directory, it will fail, because there is no such file.
    You can fix this by adding -maxdepth 1 to prevent find from looking in subdirectories.
  2. If the user runs the script with a parameter of my_subdir/test.txt, then find will fail, because the argument to -name may not contain slashes.
  3. If you have a really mischievous user, he might type "*" just to cause trouble.

Using find . seems a little silly when you don’t actually want to search a directory tree.  You know the name of the file; you just want to test its properties.  Well, if you read between the lines of find(1) with one eye closed, you realize that it never actually says that the path argument(s) have to be directories — it just implies it.  It turns out that you can say

find  filename  [expression]

Applied to your question, this becomes

find "$1" -size "$2"c

As a sanity check, I recommend:

if [ -f "$1" ]  &&  find "$1" -size "$2"c | grep -q .
then
    echo OK
fi

to avoid getting an error message from find if the specified file does not exist at all (and to prevent the aforementioned mischievous user from giving the script the name of a directory).

1
  • I wonder why this answer got downvoted, I see very good points in there (the main one being: perhaps a full-blown find is overkill in this case). Commented Mar 26, 2015 at 13:14
0

In a similar manner to the grep solutions offered elsewhere, but perhaps more simply, you can just read a single line from find. That will ensure find quits (because read definitely will) at the first match, and give you a reliable return value.

find . -name test.txt -size 156c | 
read -r na && echo ok || ! echo shite

...should work just fine. If find prints anything at all it will have a trailing newline, and so read will return true for even a single match from find, but if find prints nothing then read will reach EOF before reading a \newline and so it will return an error.

2
  • @don_crissti I thought about that too, but a couple checks indicated it would would go the whole way anyway, where read wouldn't. Some other things I tried were find ... -ok OK \; -prune but I still can't figure out how -prune is actually supposed to work *(last time I tried that lesson was more than a year ago and I remember it as less than pleasant). Also find ... -exec kill 0 \; and find ... -exec sh -c 'kill \$PPID' \;. Mostly I just didn't care to write them up - read isn't special, probably. Commented Mar 26, 2015 at 18:58
  • I'm not sure this could be done with -prune (if there is a way, it's definitely beyond me). This post gives some details on how -prune works. Commented Mar 26, 2015 at 19:49

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.