I found

[ ! -f /etc/default/lxc-net ] || . /etc/default/lxc-net

in /etc/default/lxc on Ubuntu 16.04 which seems to be replacing (my own or package maintainer code)

[ -f /etc/default/lxc-net ] && . /etc/default/lxc-net

Since the test is counter-intuitive (in case of failure of the test about non-presence of the file run the command) I was wondering if it has any advantage over the &&-version.

2 Answers 2


Yes, if you care about the exit code of the compound statement. Try the following:

#! /bin/sh -

! "$@" || true
echo "$?"

"$@" && true
echo "$?"

then run it with true and false as arguments.

./script true

./script false

This is because short-circuit evaluation of boolean expressions.

In OP's example, let's suppose the file doesn't exist:

  • In the first case, the first condition returns TRUE, no need to evaluate the second operation (TRUE OR x = TRUE). You get a TRUE for the compound statement.
  • In the second case, the first condition returns FALSE, no need to evaluate the second operation (FALSE AND x = FALSE). You get a FALSE for the compound statement.

Exit codes are very important. Check What does set -e mean in a bash script? to see possible implications of set -e, trap and set -o pipefail.

  • 3
    You might want to point to the -e option as one reason one might well care very much about exit codes.
    – JdeBP
    May 17, 2016 at 15:22
  • @JdeBP: In stackoverflow.com/questions/19622198/…, the most accepted answer is to use trap instead of set -e. Besides that, there is the recommendation of also setting set -o pipefail.
    – mmoya
    May 17, 2016 at 15:54
  • @JdeBP though a || b/a && b seems like the one place where you wouldn't care about the exit code of a w.r.t set -e, since set -e will only be triggered by the final command in the chain (the Bash manual says: "The ERR trap is not executed if the failed command is ... part of a command executed in a && or || list except the command following the final && or ||... These are the same conditions obeyed by the errexit (-e) option. " )
    – muru
    Nov 22, 2023 at 11:54

[ -f file ] is true when file exists and is a plain file.

[ ! -f file ] is true when file does not exist or is another file type.

So there is no real difference - except for readability.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .