Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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"

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 doesnt enter the if.

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

share|improve this question
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

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

if [[ ! -f /etc/benchmarking/code ]] || [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
  • 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 dont get any errors, it just doesnt 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"

Then you'll see the execution.

$ ./test.sh
+ [[ ! -f /etc/benchmarking/code ]]
+ [[ ! -f /etc/benchmarking/code.class ]]
+ echo match
share|improve this answer
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

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 ]]; 
  echo "match"
share|improve this answer

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.

[ ! -f ${var} -o -f {var}.class ] && echo "match"
share|improve this answer
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

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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