why this bash script works?

why this bash script works?
typescript
Ethan Jackson

git diff normally will not generate an output, if the two commits it compares are identical, to make it generate explicitly "the two commits are the same", I found the bash script below.

function git_diff() { # case 1: command line too few parameters if [ $# -lt 2 ]; then echo "Usage: git_diff_message <commit1> <commit2> [git-diff options...]" >&2 return 1 fi if output=$(git diff "$@" 2>&1); then if [ -z "$output" ]; then # case 2: two commits are the same echo "These two commits $@ are the same." else # case 3: two commits are different echo "Git command output: $output" fi else # case 4: Git command failed (e.g., git diff commit1 abcd, where abcd is ambiguous) echo "Git command failed: $output" >&2 return 1 fi }

However, I'm confused here: how could the script differentiate case 2 and 4?

  • In case 2, the two commits are different, the output is empty string
  • In case 4, the git command failed, e.g. git commit1 abce, here abcd parameter is ambiguous, and the output is again empty.

how could the script still works?

Answer

Every program has standard streams — stdin, stdout, stderr. But also every program when finished returns to caller an exit code. Usually exit code 0 means "everything Ok" and non-zero exit code means "there was an error, see stderr for details".

The script checks exit code in if. If git diff failed and returned non-zero exit code if immediately jumps to code inside else.

BTW, if [ -z "$output" ] works the same way. [ is a program (/bin/test linked to /bin/[, check with ls -l "/bin/["); it parses its arguments (-z, content of "$output" passed by shell, ]), interprets the test and returns an exit code; 0 in case if the output is empty, non-0 if not empty. if just checks the exit code, no magic, and jumps to the code under then or else.

Related Articles