Bash conditionals: how to "and" expressions? (if [ ! -z $VAR && -e $VAR ])

BashShell

Bash Problem Overview


I guess I'm not clear on how to do "and" tests. I wanted to make sure an argument existed which was working well with [ -e $VAR ], but it turns out that was also evaluating as true on an empty string; which I do not want.

How do I 'and' them together? Or is there another unary test that accomplishes what I want?

Bash Solutions


Solution 1 - Bash

if [ ! -z "$var" ] && [ -e "$var" ]; then
      # something ...
fi

Solution 2 - Bash

From the bash manpage:

> [[ expression ]] - return a status of 0 or 1 depending on the evaluation of the conditional expression expression.

And, for expressions, one of the options is:

> expression1 && expression2 - true if both expression1 and expression2 are true.

So you can and them together as follows (-n is the opposite of -z so we can get rid of the !):

if [[ -n "$var" && -e "$var" ]] ; then
    echo "'$var' is non-empty and the file exists"
fi

However, I don't think it's needed in this case, -e xyzzy is true if the xyzzy file exists and can quite easily handle empty strings. If that's what you want then you don't actually need the -z non-empty check:

pax> VAR=xyzzy
pax> if [[ -e $VAR ]] ; then echo yes ; fi
pax> VAR=/tmp
pax> if [[ -e $VAR ]] ; then echo yes ; fi
yes

In other words, just use:

if [[ -e "$var" ]] ; then
    echo "'$var' exists"
fi

Solution 3 - Bash

if [ -n "$var" -a -e "$var" ]; then
    do something ...
fi

 

Solution 4 - Bash

Simply quote your variable:

[ -e "$VAR" ]

This evaluates to [ -e "" ] if $VAR is empty.

Your version does not work because it evaluates to [ -e ]. Now in this case, bash simply checks if the single argument (-e) is a non-empty string.

From the manpage: > test and [ evaluate conditional expressions using a set of rules based on the number of arguments. ... > > 1 argument > >The expression is true if and only if the argument is not null.

(Also, this solution has the additional benefit of working with filenames containing spaces)

Solution 5 - Bash

I found an answer now. Thanks for your suggestions!

for e in ./*.cutoff.txt; do
if grep -q -E 'COX1|Cu-oxidase' $e
then
    echo xyz >$e.match.txt
else
    echo
fi

if grep -q -E 'AMO' $e
then
    echo abc >$e.match.txt
else
    echo
fi; done

Any comments on that? It seems inefficient to grep twice, but it works...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionatxdbaView Question on Stackoverflow
Solution 1 - Bashjaypal singhView Answer on Stackoverflow
Solution 2 - BashpaxdiabloView Answer on Stackoverflow
Solution 3 - BashSlava SemushinView Answer on Stackoverflow
Solution 4 - Bashuser123444555621View Answer on Stackoverflow
Solution 5 - BashrororoView Answer on Stackoverflow