spraff
spraff

Reputation: 33405

What's wrong with this bash negation of a logical expression?

This bash doesn't parse

if ! [[ mkdir -p "$available"
     && mkdir -p "$enabled"
     && mkdir -p "$logroot"
     && chmod 755 "$available" "$enabled" "$logroot" ]]
then
    echo "Could not make $available, $enabled, and $logroot."
    exit 1;
fi

What's the correct form?

Upvotes: 0

Views: 68

Answers (2)

anubhava
anubhava

Reputation: 785266

You can use it like this in BASH:

if ! { mkdir -p "$available" &&
     mkdir -p "$enabled" &&
     mkdir -p "$logroot" &&
     chmod 755 "$available" "$enabled" "$logroot"; }
then
    echo "Could not make $available, $enabled, and $logroot."
fi
  • && allows you to enter next command in newline
  • Instead of ! [[ ... ]] you should use ! { ... } as [[ ... ]] is used for evaluating conditional expressions.

Upvotes: 1

janos
janos

Reputation: 124656

If you want to execute multiple commands chained with &&, then [[ ... ]] is not appropriate. It seem this is what you intended:

if ! { mkdir -p "$available" &&
     mkdir -p "$enabled" &&
     mkdir -p "$logroot" &&
     chmod 755 "$available" "$enabled" "$logroot"; }
then
    echo "Could not make $available, $enabled, and $logroot."
    exit 1
fi

To answer your follow-up question, the equivalent of if(!(a && !b && c)) would be:

if ! (a && ! b && c); then
    # ...
fi

That is, ! binds only to the term next to it, and you need to put a space around !. (Thanks @that-other-guy)

Or even better, you can avoid a (...) subshell by using grouping within { ...; } instead (thanks @charles-duffy):

if ! { a && ! b && c; }; then
    # ...
fi

Upvotes: 2

Related Questions