7

I have an if in my bash script that has to check if EITHER of the 2 files exists, if they don't exist it should echo match.

Code I have:

if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

But this doesn't not seem to work for some reason.

I am 110% sure that these 2 files do not exist. I don't get any errors, it just doesn't enter the if.

I am new to bash scripting so I'm not sure what could be wrong.

  • I don't think any of the answers posted actually address the question. What happens when you try the tests individually? Do [[ ! -f /etc/.../... ]]; echo $? for each. – jw013 Sep 13 '12 at 13:52
  • A warning: [[ -f xxx ]] returns true if xxx exists and is a regular file (or a symlink to a regular file). It will return false if it doesn't exist, or if it can't tell if it exists or not or if it exists but is not a regular file (directory, pipe, device, socket...) or if it's a symlink to a file that doesn't exist or it can't tell if it exists or not or is not a regular file... [[ -e $file ]] || [[ -L $file ]] is closer to a test for existence. ls -d -- "$file" > /dev/null 2>&1 is even closer. And as a rule, this kind of test leads to race conditions. Maybe there's another way. – Stéphane Chazelas Sep 14 '12 at 20:37
9

If you want either then you want OR, not AND.

if [[ ! -f /etc/benchmarking/code ]] || [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
  • This will match if either or both files are missing.
  • Your code will only print match if both do not exist.

But, you said:

I am 110% sure that these 2 files do not exist. I don't get any errors, it just doesn't enter the if.

So your statement contradicts itself. At least one of those files must exist, if you are running that code.

If you want to see how your if statement is evaluating, run it with -x.

#!/bin/bash -x
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Then you'll see the execution.

$ ./test.sh
+ [[ ! -f /etc/benchmarking/code ]]
+ [[ ! -f /etc/benchmarking/code.class ]]
+ echo match
match
$ 
  • I want it to echo "match" if neither file exists, if one does exist it doesnt print match. I will try it with -x – Peppercat101 Sep 13 '12 at 9:46
  • In that case your original code should be fine. And indeed it works for me. – bahamat Sep 13 '12 at 17:55
3

Shouldn't that be like this ? A is a file or B is a file, then blabla.

if [[ -f /etc/benchmarking/code ]] || [[ -f /etc/benchmarking/code.class ]]; 
then  
  echo "match"
fi
3

This may also work for what you are trying to do. Single brackets are not commonly used today with bash, but this is still an option. Using '-o' is effectively an "OR" operation, and "!" negates the condition.

var=/etc/benchmarking/code
[ ! -f ${var} -o -f {var}.class ] && echo "match"
  • Don't ever use [ in bash. Aside from that, I fail to see how this answers the question. – jw013 Sep 13 '12 at 13:52
  • [ ! -f ${var} -a ! -f {var}.class ] && echo "match" it should be. The quest was: if they (both) don't exist it should echo match. – hschou Sep 2 '16 at 15:56
0

Your code satisfies your requirements: it will print match provided that it can't find either file.

Therefore the reason match is not being printed is elsewhere. You should confirm that the code block is being reached, which you can do by surrounding it with a couple of debug message. For example, like this:

echo '@ About to enter if...fi block'
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
echo '@ Finished if...fi block'

My usual preference is for debugging messages to go to stderr so as to avoid interrupting the flow of data to stdout, but I have avoided that here because you said you were a beginner. Here is one example showing how you could write to stdout:

echo '@ About to enter if...fi block' >&2

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.