0

I'm trying to do use the return for a function in an if statement within bash.

I've come up with this very simple example which unfortunately fails.

always_false () {
        return 1
}

always_true () {
        return 0
}

if [ always_false ]
then
  echo 'it is true'
else
  echo 'it is false'
fi

if [ always_true ]
then
  echo 'it is true'
else
  echo 'it is false'
fi

Returns

it is true

it is true

I would expect it to return

it is false

it is true

The actual example of what i'm trying to achieve is checking the disk space for a particular directory. But I thought the simpler example would be better for understanding where i'm going wrong.

check_space () {
  spaceAvailable=$(($(stat -f --format="%a*%S" /path/to/dir)))
  fiftyGig=50000000000
  if [ $spaceAvailable -gt $fiftyGig ]
  then
    return 0
  else
    return 1
  fi
}

if [ check_space ]
  echo 'do some things here'
else
  echo 'not enough disk space'
fi

I found another answer that suggested I should be doing something like this:

always_false () {
        [[ 0 -gt 1 ]]
        return
}

always_true () {
        [[ 2 -gt 1 ]]
        return
}

But this did not seem to work and always came up true.

John Mellor
  • 2,351
  • 8
  • 45
  • 79

3 Answers3

3

Just remove the brackes:

if always_false
then
  echo 'it is true'
else
  echo 'it is false'
fi

if always_true
then
  echo 'it is true'
else
  echo 'it is false'
fi
ichramm
  • 6,437
  • 19
  • 30
3

Modify your function like that:

#!/bin/bash

check_space () {
    spaceAvailable=$(($(stat -f --format="%a*%S" /path/to/dir))) || exit
    fiftyGig=50000000000
    ((spaceAvailable > fiftyGig))
}

if check_space
then
    echo 'do some things here'
else
    echo 'not enough disk space'
fi

Note that if [ check_space ] does not do what you think it does: The function check_space won't be called at all. The check_space is merely a string for the test ([) command. [ string ] checks for the length of the string: If the string is non-empty then it will return true, and return false otherwise.

You may also consider passing the path and size as an argument to the function:

#!/bin/bash

check_space () {
    spaceAvailable=$(($(stat -f --format="%a*%S" "$1"))) || exit
    ((spaceAvailable > "$2"))
}

if check_space /path/to/dir 50000000000
then
    echo 'do some things here'
else
    echo 'not enough disk space'
fi
M. Nejat Aydin
  • 9,597
  • 1
  • 7
  • 17
2

To further your understanding of the answers, at a bash prompt enter help if

$ help if
if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
    Execute commands based on conditional.
...

Note that the first argument is "COMMANDS", not "[ COMMANDS ]" -- if executes "COMMANDS" and branches based on the exit status:

  • exit status zero is "true"
  • any other status is "false"

You can think of [...] (and [[...]] and ((...))) as the command to run: "what's the exit status of that conditional command?"


Note that bash includes true and false as builtin commands:

if true; then echo "always true"; else echo "this is not printed"; fi
glenn jackman
  • 238,783
  • 38
  • 220
  • 352