0

I have read this, which suggests the following compilation check:

installCheck () {
  if g++ check_opencv.cpp -o check_opencv; then
    return 1
  else
    rm check_opencv
    return 0
  fi
}

if installCheck $0; then
  echo "OpenCV already installed, skipping"
  exit 0
fi

However, running this script gives:

check_opencv.cpp:2:33: fatal error: opencv2/core/core.hpp: No such file or directory
compilation terminated.
rm: check_opencv: No such file or directory
OpenCV already installed, skipping

which is wrong. Then I change to this:

installCheck () {
  g++ check_opencv.cpp -o check_opencv
  if [[ $? -ne 0 ]]; then

and it works fine:

check_opencv.cpp:2:33: fatal error: opencv2/core/core.hpp: No such file or directory
compilation terminated.
Cloning into 'opencv-2.4.9'...

Why is that? Because of some behavior of [[ or g++?

Someone in this says that "Sadly as it turns out make returns 0 weather or not it fails." Shouldn't g++ always return non-zero value when it fails? Maybe I miss something obvious, so please clarify for me. Thank you very much!

Update: it turns out that I understand bash wrongly. A return value of 0 evaluates to true in bash, which is contradictory to what I thought before. This helps.

Community
  • 1
  • 1
Yunsheng Bai
  • 219
  • 4
  • 15

2 Answers2

3
if g++ check_opencv.cpp -o check_opencv; then
  return 1

will return failure (1) if the compilation succeeds. Apparently, you wanted to return failure if the compilation failed, which would be:

if ! g++ check_opencv.cpp -o check_opencv; then
  return 1

Or you could just put the true and false branches in the correct order:

installCheck () {
  if g++ check_opencv.cpp -o check_opencv; then
    rm check_opencv
    return 0
  else
    return 1
  fi
}

I don't see anywhere in the linked question where it suggests the code which you proposed.

I suppose that your intention was to avoid contaminating the filesystem if the compilation succeeds, since the compilation itself is the only test needed. You could also achieve this with:

installCheck () {
  g++ check_opencv.cpp -o check_opencv
  local rv=$?
  rm -f check_opencv
  return rv
}
rici
  • 234,347
  • 28
  • 237
  • 341
  • What is the difference between "if [[ ! $(g++ check_opencv.cpp -o check_opencv) ]]; then" and " if ! g++ check_opencv.cpp -o check_opencv; then"? The latter one does not work when opencv is already installed. Thanks! – Yunsheng Bai Aug 22 '16 at 15:45
  • @YunshengBai: They are completely different things. The first one is not very meaningful: it succeeds if the `g++` command does not print anything to `stdout` (which is normal since `g++` normally prints errors to `stderr`). The second one tests if `g++` returned a failure code. You'll need to be clearer about what you mean by "the latter one does not work". – rici Aug 22 '16 at 15:53
  • Thank you! I am completely new to bash programming, and I will learn it. – Yunsheng Bai Aug 22 '16 at 16:00
0

if cmd; ... is "true" if cmd is successful i.e. exit status of cmd is 0 - it is logically equivalent to cmd; if [[ $? -eq 0 ]]; ...