15

I have a script that checks the exit status of the following function:

function is_git_repository {                                                    
    git branch &> /dev/null                                                     
}  

Which returns 0 if you're in a git repo, and 128 if you're not.

I have no problem testing to see if the return value is 0; the following works as expected:

if is_git_repository ; then 
    echo you are in a git repo
else 
    echo you are NOT in a git repo
fi

But it's when I'm trying to test for an exit status that is anything OTHER than 0 when I'm running into problems. I've tried the following, but none of them work:

  1. if [[ "$(is_git_repository)" != "0" ]] ; ... always evaluates to true (link)
  2. if [[ "$(is_git_repository)" -ne "0" ]] ; ... always evaluates to false
  3. if [[ "$(is_git_repository)" != 0 ]] ; ... always evaluates to true
  4. if [[ "$(is_git_repository)" -ne 0 ]] ; ... always evaluates to false
  5. if [[ ! "$(is_git_repository)" ]] ; ... always evaluates to true
  6. if !is_git_repository ; ... just echoes the command back to me, but without the bang (wtf?)

What is the correct way to check for a non-zero exit status of a command in an if statement?

Community
  • 1
  • 1
3cheesewheel
  • 9,133
  • 9
  • 39
  • 59

2 Answers2

16

I soon figured out that if ! is_git_repository ; then ... works as intended (look under 7.1.2.1. Testing exit status in Introduction to if), but why? I would have expected that #1 would work at the very least, but I don't know why it doesn't.

Also, what is up with #6?!

3cheesewheel
  • 9,133
  • 9
  • 39
  • 59
  • 4
    When you say `"$(is_git_repository)"` you get back the *standard output* of the command, not the *exit status*. You redirect stdout and stderr, so that's always the empty string which is always not equal to the string "0". bash is whitespace sensitive so the `!` needs to stand alone. As @devnull mentions, if you want the exit status you need the `$?` variable. – glenn jackman Jul 03 '13 at 19:43
  • @glennjackman Thanks! That explains it. What about the ones with `-ne` though? Why are they evaluated differently than the ones with `!=`? (i.e. why is an empty string "equal" to "0"/0 with `-ne` but not equal to "0"/0 with `!=`?) – 3cheesewheel Jul 03 '13 at 20:00
  • 1
    The [shell arithmetic](http://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic) section of the manual says: "A null value evaluates to 0." – glenn jackman Jul 03 '13 at 20:09
  • #6 is history expansion, and only happens in interactive shells. It prints the matching command from your history and then runs it. – that other guy Jul 03 '13 at 20:19
6

Consider boolean shortcut instead of an if statement:

is_git_repository || echo you are NOT in a git repo
Christoph2
  • 143
  • 1
  • 6