5

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

7

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
0
0

./script false
0
1

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
  • 3
    You might want to point to the -e option as one reason one might well care very much about exit codes. Commented 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. Commented 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. " ) Commented Nov 22, 2023 at 11:54
0

[ -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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.